添加Nginx与Gunicorn后WebSocket无法连接的问题求助
Django-React实时聊天WebSocket连接失败排查(Gunicorn+Nginx环境)
我正在开发一个Django-React应用,用Django Channels实现WebSocket做实时聊天功能,但加了Gunicorn和Nginx之后,前端连不上WebSocket,不确定Nginx配置是否正确。
当前Nginx配置(nginx.conf)
server { listen 80; server_name 0.0.0.0; location / { proxy_pass http://0.0.0.0:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location /ws/ { proxy_pass http://0.0.0.0:8000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location /static/ { alias /app/staticfiles/; } }
Dockerfile配置
FROM python:3.9 ENV PYTHONUNBUFFERED=1 WORKDIR /usr/src/referralhub RUN apt-get update && apt-get install -y libsasl2-dev libldap2-dev libssl-dev COPY requirements.txt /tmp/requirements.txt RUN pip install --no-cache-dir -r /tmp/requirements.txt && rm -rf /tmp/requirements.txt WORKDIR /app COPY . . RUN pip install gunicorn RUN python manage.py collectstatic --noinput CMD ["gunicorn", "--bind", "0.0.0.0:8000", "referralhub.wsgi:application"]
docker-compose.yml配置
version: "3.9.18" services: django: build: . container_name: django command: gunicorn referralhub.wsgi:application --bind 0.0.0.0:8000 volumes: - .:/app ports: - "8000:8000" environment: - DEBUG=1 - DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1] - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} depends_on: - redis redis: image: "redis:alpine" nginx: image: nginx:alpine ports: - "80:80" volumes: - ./nginx.conf:/etc/nginx/conf.d/default.conf - static_volume:/app/staticfiles depends_on: - django volumes: static_volume:
asgi.py配置
""" ASGI config for referralhub project. It exposes the ASGI callable as a module-level variable named ``application``. For more information on this file, see https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/ """ import os from django.core.asgi import get_asgi_application from channels.routing import ProtocolTypeRouter, URLRouter from channels.auth import AuthMiddlewareStack import backend.routing os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'referralhub.settings') application = ProtocolTypeRouter({ 'http': get_asgi_application(), 'websocket': AuthMiddlewareStack( URLRouter( backend.routing.websocket_urlpatterns ) ) })
settings.py相关配置
INSTALLED_APPS = [ 'channels', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django_extensions', 'backend', 'corsheaders', ] ASGI_APPLICATION = 'referralhub.asgi.application' CHANNEL_LAYERS = { "default": { "BACKEND": "channels_redis.core.RedisChannelLayer", "CONFIG": { "hosts": [("redis", 6379)], }, }, }
问题排查与修复方案
1. 核心问题:Gunicorn不支持ASGI协议
Gunicorn是WSGI服务器,无法处理WebSocket依赖的ASGI请求,必须替换为支持ASGI的服务器(如Daphne或Uvicorn)。
修复步骤:
- 在
requirements.txt中添加daphne,重新构建镜像 - 修改Dockerfile的启动命令:
CMD ["daphne", "-b", "0.0.0.0", "-p", "8000", "referralhub.asgi:application"] - 修改docker-compose.yml中django服务的command:
command: daphne referralhub.asgi:application --bind 0.0.0.0 --port 8000
2. Nginx配置优化
Docker容器间通信需使用服务名而非0.0.0.0,同时添加WebSocket超时配置避免连接断开:
server { listen 80; server_name 0.0.0.0; location / { proxy_pass http://django:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location /ws/ { proxy_pass http://django:8000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 添加WebSocket超时配置 proxy_connect_timeout 7d; proxy_send_timeout 7d; proxy_read_timeout 7d; } location /static/ { alias /app/staticfiles/; } }
3. 允许主机配置
更新settings.py中的DJANGO_ALLOWED_HOSTS,包含Docker服务名:
DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1] django nginx
4. 前端连接地址校验
确保前端WebSocket连接地址为ws://你的域名/ws/(生产环境用wss://),路径需与后端routing配置一致。
内容的提问来源于stack exchange,提问作者Allen Ye
相关产品推荐
相关产品推荐

