Docker Compose部署Django+Gunicorn+Nginx报错排查求助
问题描述
我在通过Nginx部署Django-Gunicorn应用服务器时遇到配置问题,无法定位错误(暂未关注静态资源),访问http://localhost时出现502网关错误。
Docker Compose 配置
# 指定Dockerfile的格式 version: "3.9" # 服务(容器的别名) services: # Web服务 web: build: . # 添加webpack命令以监听变更并打包到生产环境 command: gunicorn --bind unix:/run_socket/gunicorn.sock StockWhiz.wsgi:application # 以下是使用gunicorn提供服务的命令 volumes: - type: bind source: ./stockwhiz-web target: /code - type: bind source: ./run_socket target: /run_socket depends_on: - db environment: - "DJANGO_SETTINGS_MODULE=StockWhiz.settings.local" db: image: postgres:14-bullseye volumes: - postgres_data:/var/lib/postgresql/data/ # 不确定该环境变量的含义 environment: - "POSTGRES_HOST_AUTH_METHOD=trust" nginx: image: nginx:stable restart: always volumes: - ./run_socket:/run_socket - ./config/nginx/:/etc/nginx/conf.d/ ports: - "80:80" depends_on: - web # 卷配置 volumes: postgres_data:
Nginx 配置
# 注意:在Docker Compose中,该文件通常位于etc/nginx/conf.d/ # 会自动被包含到etc/nginx/nginx.conf文件中 upstream gunicorn_application { server unix:/run_socket/gunicorn.sock; } server{ listen 80; server_name www.stockwhiz.in; error_log stderr warn; access_log /dev/stdout main; location / { include /etc/nginx/uwsgi_params; uwsgi_pass gunicorn_application; } }
日志信息
stockwhizfullfiles-web-1 | [2022-12-09 06:05:27 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:63) stockwhizfullfiles-nginx-1 | 2022/12/09 06:05:27 [error] 38#38: *25 upstream prematurely closed connection while reading response header from upstream, client: 172.25.0.1, server: www.stockwhiz.in, request: "GET / HTTP/1.1", upstream: "uwsgi://unix:/run_socket/gunicorn.sock:", host: "localhost" stockwhizfullfiles-nginx-1 | 172.25.0.1 - - [09/Dec/2022:06:05:27 +0000] "GET / HTTP/1.1" 502 559 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.42" "-" stockwhizfullfiles-web-1 | [2022-12-09 06:05:27 +0000] [63] [INFO] Worker exiting (pid: 63) stockwhizfullfiles-web-1 | [2022-12-09 06:05:27 +0000] [64] [INFO] Booting worker with pid: 64 stockwhizfullfiles-nginx-1 | 2022/12/09 06:05:58 [error] 38#38: *25 upstream prematurely closed connection while reading response header from upstream, client: 172.25.0.1, server: www.stockwhiz.in, request: "GET /favicon.ico HTTP/1.1", upstream: "uwsgi://unix:/run_socket/gunicorn.sock:", host: "localhost", referrer: "http://localhost/" stockwhizfullfiles-web-1 | [2022-12-09 06:05:58 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:64) stockwhizfullfiles-nginx-1 | 172.25.0.1 - - [09/Dec/2022:06:05:58 +0000] "GET /favicon.ico HTTP/1.1" 502 559 "http://localhost/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.42" "-" stockwhizfullfiles-web-1 | [2022-12-09 06:05:58 +0000] [64] [INFO] Worker exiting (pid: 64) stockwhizfullfiles-web-1 | [2022-12-09 06:05:58 +0000] [79] [INFO] Booting worker with pid: 79
问题排查与解决步骤
1. 修复Nginx与Gunicorn的协议不匹配
你的Nginx配置用了uwsgi_pass,但Gunicorn默认走HTTP协议,不是uWSGI协议,这是导致502的核心原因。两种修复方式:
- 推荐方案:改用HTTP代理
修改Nginx配置的location /块:location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_pass http://unix:/run_socket/gunicorn.sock; } - 备选方案:让Gunicorn用uWSGI协议启动
修改web服务的command:command: gunicorn --bind unix:/run_socket/gunicorn.sock StockWhiz.wsgi:application -k uwsgi
2. 解决Gunicorn Worker超时问题
日志里的WORKER TIMEOUT大概率是Django连数据库超时导致的:
- 检查Django配置文件里的数据库HOST是否设为
db(Docker Compose里的数据库服务名),容器间只能通过服务名通信,不能用localhost; - 确认Django的数据库用户名和PostgreSQL默认用户
postgres匹配,POSTGRES_HOST_AUTH_METHOD=trust允许无密码连接,但要保证用户名对应。
3. 检查Socket目录权限
确保/run_socket目录的读写权限同时对Gunicorn和Nginx开放:
- 在Web服务的Dockerfile里添加:
RUN mkdir -p /run_socket && chmod 777 /run_socket
4. 保证数据库就绪后再启动Web服务
depends_on只保证容器启动顺序,不保证数据库服务完全就绪。可以给Web服务加启动延迟,或者用脚本检测数据库连接:
修改web服务的command:
command: > sh -c "python manage.py wait_for_db && gunicorn --bind unix:/run_socket/gunicorn.sock StockWhiz.wsgi:application"
wait_for_db是Django自定义脚本,用于等待数据库可用(脚本逻辑可以是循环尝试连接数据库,直到成功)。
内容的提问来源于stack exchange,提问作者Savakar Rohan
相关产品推荐
相关产品推荐

