Как я могу заставить приложение Django подключиться к серверу minio, когда оба находятся за прокси-сервером nginx и внутри отдельных контейнеров docker?
Гол
Доступ к серверу minio через поддомен с сервера Django в среде docker (и сервер minio, и сервер Django находятся за прокси-сервером nginx)
Ожидаемый результат: Django может получить доступ к серверу minio, используя поддомен, указанный в nginx.
Я могу успешно открыть консоль minio через s3-console.localhost
Проблема
Служба Django не может правильно подключиться. Журналы Docker:
Context
nginx.config
user nginx;
events {
worker_connections 1000;
}
http {
server {
server_name api.lamanin.com api.localhost;
location / {
proxy_pass http://api:8000;
}
}
server {
server_name s3.lamanin.com s3.localhost;
listen 80;
location / {
proxy_pass http://s3:9000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
server_name s3-console.lamanin.com s3-console.localhost;
listen 80;
location / {
proxy_pass http://s3:9090;
}
}
server {
server_name lamanin.com *.lamanin.com localhost *.localhost;
listen 80;
location / {
proxy_pass http://web:3000;
}
location /ws {
proxy_pass http://web:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
}
}
docker-compose.yml
version: "3.8"
services:
s3:
image: minio/minio
container_name: s3
restart: on-failure
ports:
- "9000:9000"
- "9090:9090"
volumes:
- s3:/data
environment:
- MINIO_ROOT_USER=${MINIO_ROOT_USER}
- MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD}
command: server --console-address :9090 --address :9000 /data
web:
image: lamanin/web
container_name: web
environment:
- WDS_SOCKET_PORT=${WDS_SOCKET_PORT}
- ESLINT_NO_DEV_ERRORS=${ESLINT_NO_DEV_ERRORS}
- REACT_APP_API_URL=${REACT_APP_API_URL}
- REACT_APP_SHOW_COMING_SOON=${REACT_APP_SHOW_COMING_SOON}
build:
context: ./web
dockerfile: Dockerfile.${ENVIRONMENT}
restart: on-failure
volumes:
- web:/app/src
ports:
- "${WEB_PORT}"
depends_on:
- api
db:
image: postgres
container_name: "db"
hostname: "db"
volumes:
- db:/var/lib/postgresql/data
environment:
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
api:
image: lamanin/api
environment:
- SECRET_KEY=${SECRET_KEY}
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- DJANGO_SUPERUSER_USERNAME=${DJANGO_SUPERUSER_USERNAME}
- DJANGO_SUPERUSER_PASSWORD=${DJANGO_SUPERUSER_PASSWORD}
- MINIO_URL=${MINIO_URL}
- MINIO_DOMAIN=${MINIO_DOMAIN}
- MINIO_SA_ACCESS_KEY=${MINIO_SA_ACCESS_KEY}
- MINIO_SA_SECRET_KEY=${MINIO_SA_SECRET_KEY}
- API_URL=${API_URL}
container_name: api
build:
context: ./api
restart: on-failure
command: >
sh -c "sleep 10 && python3 manage.py collectstatic --no-input &&
python3 manage.py migrate &&
python3 manage.py ensure_admin &&
python3 manage.py runserver 0.0.0.0:8000"
volumes:
- api:/code
ports:
- "${API_PORT}"
depends_on:
- db
- s3
nginx:
build:
context: .
dockerfile: Dockerfile.nginx
container_name: "nginx"
restart: on-failure
depends_on:
- api
- web
- s3
ports:
- "80:80"
volumes:
api:
web:
db:
s3:
Соответствующие настройки Django
AWS_ACCESS_KEY_ID = os.getenv('MINIO_SA_ACCESS_KEY')
AWS_SECRET_ACCESS_KEY = os.getenv('MINIO_SA_SECRET_KEY')
AWS_STORAGE_BUCKET_NAME = 'main'
AWS_S3_ENDPOINT_URL = os.getenv('MINIO_URL')
AWS_S3_OBJECT_PARAMETERS = {
'CacheControl': 'max-age=86400',
}
AWS_STATIC_LOCATION = 'static'
STATICFILES_STORAGE = 'ezevent_api.storage_backends.StaticStorage'
STATIC_URL = f'{AWS_S3_ENDPOINT_URL}/{AWS_STORAGE_BUCKET_NAME}/'
AWS_PUBLIC_MEDIA_LOCATION = 'media/public'
DEFAULT_FILE_STORAGE = 'ezevent_api.storage_backends.PublicMediaStorage'
AWS_PRIVATE_MEDIA_LOCATION = 'media/private'
PRIVATE_FILE_STORAGE = 'ezevent_api.storage_backends.PrivateMediaStorage'
client = Minio(
os.getenv('MINIO_DOMAIN'),
access_key=AWS_ACCESS_KEY_ID,
secret_key=AWS_SECRET_ACCESS_KEY,
secure=os.getenv('MINIO_SECURE') == 'True'
)
found = client.bucket_exists(AWS_STORAGE_BUCKET_NAME)
if not found: client.make_bucket(AWS_STORAGE_BUCKET_NAME)
Переменные окружения
MINIO_URL=http://s3.localhost
MINIO_DOMAIN=s3.localhost
MINIO_ROOT_USER=admin
MINIO_ROOT_PASSWORD=[REDACTED]
MINIO_SA_ACCESS_KEY=service-account-1
MINIO_SA_SECRET_KEY=[REDACTED]
MINIO_SECURE=False
Соответствующие пакеты
https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html
То, что я пробовал
Изначально я не использовал никаких заголовков в настройках прокси, поэтому я добавил несколько заголовков, которые я нашел из этой темы на github: https://github.com/minio/minio/issues/7661.
Я подозревал, что адрес
http://s3:9000
не распознается nginx, поэтому я использовалhttp://localhost:9000
, но локальный хост nginx, вероятно, отличается от сервисаs3
, потому что они находятся в разных контейнерах.При запуске службы
s3
& nginx с помощью docker, и запуске сервера Django вне docker (запуск вручную с помощью командыpython manage.py runserver
) он успешно подключается к серверу minio, если используетсяlocalhost:9000
. Но терпит неудачу, если используется поддоменhttp://s3.localhost
.