You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 11:10:41