Работа с сервером django, react и nginx с помощью docker
Я новичок в nginx и пытаюсь понять, как он работает. Я создаю и докеризирую сайт, используя react для frontend и django для backend, и обслуживаю как react, так и django api с помощью nginx. Но когда я обращаюсь к localhost, который должен обслуживать приложение react, все работает хорошо. Проблема возникает, когда я хочу получить доступ, например, к localhost/docs или localhost/admin, которые должны обслуживаться gunicorn и django. Я всегда получаю плохой запрос (400)
В моем settings.py у меня есть
ALLOWED_HOSTS = []
ALLOWED_HOSTS.extend(
filter(
None,
os.environ.get('ALLOWED_HOSTS', '').split(' '),
)
)
STATIC_URL = '/static/static/'
MEDIA_URL = '/static/media/'
MEDIA_ROOT = '/vol/web/mediafiles'
STATIC_ROOT = '/vol/web/staticfiles'
мой файл .env
DB_NAME=dbname
DB_USER=rootuser
DB_PASS=dbpassword
DJANGO_SECRET_KEY=secretkey_for_production_environment
DJANGO_ALLOWED_HOSTS=localhost
Вот файл docker-compose-prod.yml
version: "3.9"
services:
db:
image: postgres:13-alpine
container_name: db-prod-c
restart: always
volumes:
- db-prod:/var/lib/postgresql/data
environment:
- POSTGRES_DB=${DB_NAME}
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_PASS}
backend:
build:
context: ./backend
dockerfile: Dockerfile.prod
#restart: always
image: api-prod-i:django-prod
container_name: api-prod-c
user: root
volumes:
- mediafiles:/vol/web/mediafiles
- staticfiles:/vol/web/staticfiles
environment:
- DB_HOST=db
- DB_NAME=${DB_NAME}
- DB_USER=${DB_USER}
- DB_PASS=${DB_PASS}
- SECRET_KEY=${DJANGO_SECRET_KEY}
- ALLOWED_HOSTS=${DJANGO_ALLOWED_HOSTS}
expose:
- 8000
depends_on:
- db
# networks:
# - django-network
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
#restart: always
image: client-prod-i:django-prod
container_name: client-prod-c
volumes:
- react-build:/frontend/build
depends_on:
- backend
proxy:
build:
context: ./webserver
dockerfile: Dockerfile
image: proxy-i
container_name: proxy-c
#restart: always
ports:
- 80:80
volumes:
- staticfiles:/webserver/staticfiles
- mediafiles:/webserver/mediafiles
- react-build:/webserver/buildfiles
depends_on:
- backend
- frontend
# networks:
# - django-network
# networks:
# django-network:
# name: django-network
volumes:
db-prod:
react-build:
staticfiles:
mediafiles:
Конфигурация nginx
upstream django {
server backend:8000;
}
log_format custom_json escape=json
'{'
'"time_local":"$time_local",'
'"remote_addr":"$remote_addr",'
'"remote_user":"$remote_user",'
'"request":"$request",'
'"status": "$status",'
'"body_bytes_sent":"$body_bytes_sent",'
'"http_referrer":"$http_referer",'
'"http_user_agent":"$http_user_agent",'
'"request_time":"$request_time"'
'}';
server {
listen 80;
large_client_header_buffers 4 16k;
access_log /var/log/nginx/access.log custom_json;
error_log /var/log/nginx/error.log debug;
#error_log /var/log/nginx/error.log.info info;
#error_log /var/log/nginx/error.log.crit crit;
#error_log /var/log/nginx/error.log.warn warn;
#error_log /var/log/nginx/error.log.error error;
#error_log /var/log/nginx/error.log.alert alert;
#error_log /var/log/nginx/error.log.notice notice;
#error_log /var/log/nginx/error.log.emerg emerg;
location / {
root /webserver/buildfiles;
}
location /static/static/ {
alias /webserver/staticfiles/;
}
location /static/media/ {
alias /webserver/mediafiles/;
}
location /api {
proxy_pass http://django;
}
location /admin/ {
proxy_pass http://django;
}
location /docs {
proxy_pass http://django;
}
}
Когда я развертываю с помощью docker-compose, все работает следующим образом
api-prod-c sh entrypoint.sh Up 8000/tcp
client-prod-c docker-entrypoint.sh npm r ... Exit 0
db-prod-c docker-entrypoint.sh postgres Up 5432/tcp
proxy-c /docker-entrypoint.sh /run.sh Up 0.0.0.0:80->80/tcp,:::80->80/tcp, 8080/tcp
Я попытался изменить DJANGO_ALLOWED_HOST=localhost в .env файле на DJANGO_ALLOWED_HOST=backend, поскольку backend - это имя сервиса моего контейнера django, который используется в upstream, но все равно получаю плохой запрос (400)
Я попытался вести журнал nginx error_log и получил следующее
2022/12/21 15:28:20 [notice] 8#8: using the "epoll" event method
2022/12/21 15:28:20 [notice] 8#8: nginx/1.23.3
2022/12/21 15:28:20 [notice] 8#8: built by gcc 12.2.1 20220924 (Alpine 12.2.1_git20220924-r4)
2022/12/21 15:28:20 [notice] 8#8: OS: Linux 5.15.0-56-generic
2022/12/21 15:28:20 [notice] 8#8: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2022/12/21 15:28:20 [notice] 8#8: start worker processes
2022/12/21 15:28:20 [notice] 8#8: start worker process 9
2022/12/21 15:28:20 [notice] 8#8: start worker process 10
2022/12/21 15:28:20 [notice] 8#8: start worker process 11
2022/12/21 15:28:20 [notice] 8#8: start worker process 12
2022/12/21 15:28:20 [notice] 8#8: start worker process 13
2022/12/21 15:28:20 [notice] 8#8: start worker process 14
2022/12/21 15:28:20 [notice] 8#8: start worker process 15
2022/12/21 15:28:20 [notice] 8#8: start worker process 16
{"time_local":"","remote_addr":"","remote_user":"","request":"","status": "","body_bytes_sent":"","http_referrer":"","http_user_agent":"","request_time":""}
{"time_local":"","remote_addr":"","remote_user":"","request":"","status": "","body_bytes_sent":"","http_referrer":"","http_user_agent":"","request_time":""}
{"time_local":"","remote_addr":"","remote_user":"","request":"","status": "","body_bytes_sent":"","http_referrer":"","http_user_agent":"","request_time":""}
{"time_local":"","remote_addr":"","remote_user":"","request":"","status": "","body_bytes_sent":"","http_referrer":"","http_user_agent":"","request_time":""}
{"time_local":"","remote_addr":"","remote_user":"","request":"","status": "","body_bytes_sent":"","http_referrer":"","http_user_agent":"","request_time":""}
{"time_local":"","remote_addr":"","remote_user":"","request":"","status": "","body_bytes_sent":"","http_referrer":"","http_user_agent":"","request_time":""}
Я не знаю, что происходит, когда я хочу получить доступ к моему бэкенду.