Docker部署Nginx反向代理Django应用服务器端502故障排查
502 Bad Gateway 排查思路(Docker部署Nginx+Django)
问题描述
通过Docker部署Nginx反向代理的Django应用,本地运行正常,但部署到服务器后网页显示502 Bad Gateway错误,Nginx日志如下:
2023/01/13 07:55:56 [error] 28#28: *1 connect() failed (111: Connection refused) while connecting
to upstream, client: xx.xxx.xx.xxx, server: , request: "GET /favicon.ico HTTP/1.1", upstream:
"http://xxx.xx.x.x:8000/favicon.ico", host: "xx.xxx.xxx.xxx", referrer: "http://xxx.xxx.xxx.xxx/"
相关配置文件
Nginx Dockerfile
FROM nginx:1.23.3-alpine RUN rm /etc/nginx/conf.d/default.conf COPY ./default.conf /etc/nginx/conf.d/default.conf
Nginx default.conf
upstream apii { server api:8000; } server { client_max_body_size 20M; listen 80; location / { proxy_pass http://apii; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_redirect off; } # location = /favicon.ico { access_log off; log_not_found off; } location /api { proxy_pass http://apii; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_redirect off; } location /realestateadmin { proxy_pass http://apii; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_redirect off; } location /staticfiles/ { alias /app/staticfiles/; } location /mediafiles/ { alias /app/mediafiles/; } }
docker-compose.yml
version: "3.9" services: api: build: context: . dockerfile: ./docker/local/django/Dockerfile command: /start volumes: - .:/app - static_volume:/app/staticfiles - media_volume:/app/mediafiles # ports: # - "8000:8000" expose: - 8000 env_file: - .env depends_on: - postgres-db networks: - real-estate postgres-db: image: postgres:12.0-alpine ports: - "5432:5432" volumes: - postgres_data:/var/lib/postgresql/data/ environment: - POSTGRES_USER=${DB_USER} - POSTGRES_PASSWORD=${DB_PASSWORD} - POSTGRES_DB=${DB_NAME} networks: - real-estate nginx: restart: always depends_on: - api volumes: - static_volume:/app/staticfiles - media_volume:/app/mediafiles build: context: ./docker/local/nginx dockerfile: Dockerfile ports: - "80:80" networks: - real-estate networks: real-estate: driver: bridge volumes: postgres_data: static_volume: media_volume:
排查思路
确认Django服务状态
- 查看api容器启动日志:
docker-compose logs api,检查是否有启动失败、数据库连接超时或端口绑定异常 - 进入api容器内部,验证服务监听状态:
docker-compose exec api netstat -tulpn | grep 8000,或用curl localhost:8000测试本地访问是否正常
- 查看api容器启动日志:
检查Docker网络连通性
- 在nginx容器内测试访问api服务:
docker-compose exec nginx curl http://api:8000,如果无法访问,确认两个容器是否都加入了real-estate网络 - 查看容器网络归属:
docker inspect api | grep Networks和docker inspect nginx | grep Networks,确保网络一致
- 在nginx容器内测试访问api服务:
验证Django绑定地址
- 检查Django启动脚本(/start),确保服务绑定的是
0.0.0.0:8000,而非127.0.0.1:8000。如果绑定localhost,容器外部(包括nginx)无法访问该端口
- 检查Django启动脚本(/start),确保服务绑定的是
调整服务启动顺序
depends_on仅保证postgres-db先启动,但不保证数据库完全就绪。可在api的启动脚本中加入数据库健康检查,等待postgres可连接后再启动Django- 手动重启api容器:
docker-compose restart api,观察是否能正常连接数据库并启动服务
校验Nginx配置
- 检查nginx容器内的配置文件:
docker-compose exec nginx cat /etc/nginx/conf.d/default.conf,确认upstream指向api:8000 - 测试配置语法正确性:
docker-compose exec nginx nginx -t,确保无语法错误
- 检查nginx容器内的配置文件:
排查服务器网络限制
- 确认服务器80端口对外开放,容器间的8000端口无需对外暴露,但要保证同一Docker网络内的容器可互相访问
- 检查服务器iptables规则或云服务商安全组,是否限制了容器间的网络通信
内容的提问来源于stack exchange,提问作者Abdul Fertah
相关产品推荐
相关产品推荐

