Django Daphne搭配Nginx与Docker时WSS连接故障求助
问题:Django+Daphne+Nginx环境下WebSocket连接失败
我正在部署基于Django和Daphne的应用以建立WebSocket连接。本地未使用Nginx时一切正常,但生产环境中需用Nginx提供SSL/HTTPS(含WSS)服务,此时WebSocket连接会无限挂起直至失败。
我曾考虑移除Nginx,因为找到了让Daphne直接使用SSL证书运行在443端口的配置:daphne -b 0.0.0.0 -e ssl:443:privateKey=/privkey.pem:certKey=/fullchain.pem core.asgi:application
但仍需Nginx来托管静态文件。我已尝试各种方法,恳请他人提供帮助。
配置文件:docker-compose.yml
services: web: build: . container_name: meetlink_django_app ports: - 8000:8000 - 8001:8001 volumes: - .:/app - static_volume:/app/core/staticfiles - ./certbot/conf:/app/certbot/conf:ro - ./certbot/www:/app/certbot/www:ro environment: - DEBUG=True - PYTHONUNBUFFERED=1 - DJANGO_SETTINGS_MODULE=core.settings - ENV=${ENV} networks: - meetlink-network command: - bash - -c - "python manage.py migrate && python manage.py runserver 0.0.0.0:8000 & daphne -b 0.0.0.0 -p 8001 core.asgi:application" depends_on: database: condition: service_healthy cache: condition: service_healthy database: image: postgres container_name: meetlink_django_database environment: - POSTGRES_USER=${DB_USERNAME} - POSTGRES_PASSWORD=${DB_PASSWORD} - POSTGRES_DB=${DB_NAME} ports: - ${DB_PORT}:5432 volumes: - database_volume:/var/lib/postgresql/data networks: - meetlink-network healthcheck: test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER"] interval: 5s timeout: 10s retries: 5 cache: image: redis container_name: meetlink_django_cache ports: - ${CACHE_PORT}:6379 networks: - meetlink-network healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 10s retries: 5 server: image: nginx container_name: meetlink_django_server ports: - ${SSL_SERVER_PORT}:443 - ${SERVER_PORT}:80 depends_on: - web networks: - meetlink-network volumes: - ./.nginx/default.conf:/etc/nginx/conf.d/default.conf:ro - static_volume:/var/www/html/static - ./certbot/www/:/var/www/certbot:ro - ./certbot/conf/:/var/www/conf:ro certbot: image: certbot/certbot:latest volumes: - ./certbot/www/:/var/www/certbot/:rw - ./certbot/conf/:/etc/letsencrypt/:rw network_mode: host volumes: static_volume: database_volume: networks: meetlink-network: driver: bridge
配置文件:.nginx/default.conf
server { listen 80; listen [::]:80; server_name totemvirtual.com.br www.totemvirtual.com.br; tcp_nodelay on; location / { proxy_pass http://meetlink_django_app:8000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; proxy_buffering off; } location /ws/ { proxy_pass http://meetlink_django_app:8001; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; proxy_buffering off; } location /static/ { autoindex on; alias /var/www/html/static/; } } server { listen 443 ssl; listen [::]:443 ssl; http2 on; server_name totemvirtual.com.br www.totemvirtual.com.br; ssl_certificate /var/www/conf/live/totemvirtual.com.br/fullchain.pem; ssl_certificate_key /var/www/conf/live/totemvirtual.com.br/privkey.pem; ssl_session_timeout 1d; ssl_session_cache shared:MozSSL:10m; ssl_session_tickets off; proxy_connect_timeout 43200000; tcp_nodelay on; location / { proxy_pass http://meetlink_django_app:8001; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; proxy_buffering off; } location /static/ { autoindex on; alias /var/www/html/static/; } }
配置文件:core/asgi.py
import os from channels.auth import AuthMiddlewareStack from channels.routing import ProtocolTypeRouter, URLRouter from django.core.asgi import get_asgi_application from django.urls import re_path from meetlink.domain.call.call_consumer import CallConsumer from meetlink.domain.meeting.meeting_consumer import MeetingConsumer os.environ.setdefault("DJANGO_SETTINGS_MODULE", "core.settings") application = ProtocolTypeRouter( { "http": get_asgi_application(), "websocket": AuthMiddlewareStack( URLRouter( [ re_path("ws/calls/?$", CallConsumer.as_asgi()), re_path("ws/meetings/?$", MeetingConsumer.as_asgi()), ] ) ), } )
配置文件:core/settings.py(Channel Layers配置)
CHANNEL_LAYERS = { "default": { "BACKEND": config("CHANNELS_CACHE_ENGINE"), "CONFIG": { "hosts": [(config("CACHE_HOST"), config("CACHE_PORT"))], "prefix": "meetlink.channels", }, }, }
配置文件:Dockerfile
FROM python:3.13-slim RUN apt-get update && apt-get install -y --no-install-recommends \ gcc \ libpq-dev \ build-essential \ python3-dev \ && rm -rf /var/lib/apt/lists/* WORKDIR /app RUN pip install --no-cache-dir pipenv COPY Pipfile Pipfile.lock /app/ RUN pipenv install --system --deploy COPY . /app/ WORKDIR /app/core/ COPY start.sh /app/start.sh RUN python manage.py collectstatic --noinput --clear EXPOSE 8000 8001 443 80
内容的提问来源于stack exchange,提问作者Maciel Suassuna
相关产品推荐
相关产品推荐

