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

Docker容器内Daphne+Supervisor部署Django应用无法访问问题

问题:Docker容器内用Supervisor管理多Daphne进程导致Nginx 502错误

此前通过多容器部署单进程Daphne可正常访问,改为单容器内用Supervisor管理多Daphne进程后,日志显示应用运行正常,但无法通过浏览器访问。更新后发现:容器内执行curl localhost:8000可正常访问,但容器内外用容器IP访问均失败,Nginx返回:

502 Bad Gateway
nginx/1.18.0

现有配置

Supervisord配置

[supervisord]
nodaemon=true
[supervisorctl]

[fcgi-program:asgi]
User=root

# TCP socket used by Nginx backend upstream
socket=tcp://localhost:8000

# Directory where your site's project files are located
directory=/app

# Each process needs to have a separate socket file, so we use process_num
# Make sure to update "mysite.asgi" to match your project name
command= /usr/local/bin/daphne -u /run/daphne/daphne%(process_num)d.sock --endpoint fd:fileno=0     --access-log - --proxy-headers WBT.asgi:application

# Number of processes to startup, roughly the number of CPUs you have
numprocs=4

# Give each process a unique name so they can be told apart
process_name=asgi%(process_num)d

# Automatically start and recover processes
autostart=true
autorestart=true

# Choose where you want your log to go
stdout_logfile=/home/appuser/supervisor_log.log
redirect_stderr=true

Nginx配置

upstream django_daphne{
    
    hash $remote_addr consistent;
    
    server django_daphne_1:8000;
    server django_daphne_2:8000;
    server django_daphne_3:8000;
}

server {
    
    server_name xxx.yyy.zzz.khmm;
    listen 80;
    client_max_body_size 64M;
    location = /favicon.ico { access_log off; log_not_found off; }
    
    location / {
        proxy_pass http://django_daphne;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        #Websocket support
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
    
    location /api/ {
        proxy_pass http://api_app:8888;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    }
}

问题原因

核心矛盾在于Supervisord配置与Daphne启动命令的通信方式不匹配:

  1. Supervisord的[fcgi-program:asgi]配置了socket=tcp://localhost:8000,这会让Supervisord在容器的127.0.0.1:8000监听FastCGI请求,再转发给Daphne进程。但这个监听仅绑定本地回环地址,容器外部(包括Nginx容器)无法访问。
  2. Daphne命令中使用了--endpoint fd:fileno=0,这意味着Daphne通过Supervisord提供的文件描述符接收请求,而非直接监听TCP端口或Unix套接字对外提供服务。容器内curl localhost:8000能通是因为请求发给了Supervisord的本地监听端口,再被转发给Daphne。

修复方案

方案1:让Daphne直接监听TCP端口(容器间通信友好)

这种方案不需要依赖Supervisord的FCGI转发,让每个Daphne进程直接监听容器的所有IP,方便Nginx容器通过网络访问。

  1. 修改Supervisord配置:

    • 删除[fcgi-program:asgi]下的socket=tcp://localhost:8000(FCGI配置对ASGI的Daphne无用)
    • 调整Daphne启动命令,让每个进程监听不同的TCP端口,绑定容器的0.0.0.0(允许外部访问):
    [fcgi-program:asgi]
    # 其他配置保留
    command= /usr/local/bin/daphne -b 0.0.0.0 -p 800%(process_num)d --access-log - --proxy-headers WBT.asgi:application
    numprocs=4
    process_name=asgi%(process_num)d
    

    (800%(process_num)d会生成8000、8001、8002、8003四个端口)

  2. 更新Nginx的upstream配置,指向Daphne容器的四个端口(替换django_daphne_container为你的容器服务名):

    upstream django_daphne{
        hash $remote_addr consistent;
        server django_daphne_container:8000;
        server django_daphne_container:8001;
        server django_daphne_container:8002;
        server django_daphne_container:8003;
    }
    

方案2:使用Unix套接字(性能更优)

Unix套接字比TCP端口性能更好,适合同一宿主机的容器间通信,需要通过共享卷让Nginx容器访问Daphne的套接字文件。

  1. 在docker-compose中添加共享卷:

    services:
      django_daphne:
        volumes:
          - daphne_sockets:/run/daphne
      nginx:
        volumes:
          - daphne_sockets:/run/daphne
    volumes:
      daphne_sockets:
    
  2. 修改Supervisord配置:

    • 删除[fcgi-program:asgi]下的socket=tcp://localhost:8000
    • 调整Daphne命令,去掉--endpoint fd:fileno=0,让它直接监听Unix套接字:
    [fcgi-program:asgi]
    # 其他配置保留
    command= /usr/local/bin/daphne -u /run/daphne/daphne%(process_num)d.sock --access-log - --proxy-headers WBT.asgi:application
    
  3. 更新Nginx的upstream配置,指向共享卷中的Unix套接字:

    upstream django_daphne{
        hash $remote_addr consistent;
        server unix:/run/daphne/daphne0.sock;
        server unix:/run/daphne/daphne1.sock;
        server unix:/run/daphne/daphne2.sock;
        server unix:/run/daphne/daphne3.sock;
    }
    

验证步骤

  1. 重启Supervisord服务(或重启Daphne容器)
  2. 重启Nginx容器
  3. 在Nginx容器内执行curl http://django_daphne验证连通性,或直接通过浏览器访问域名测试

内容的提问来源于stack exchange,提问作者MijatTomić

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 17:45:11