Estoy usando docker compose para construir un proyecto con django, nginx como servicios. Cuando inicio el servidor Daphne y un cliente intenta conectarse al servidor websocket, aparece este error:
*1 recv() failed (104: Connection reset by peer) while reading response header from upstreamEl lado del cliente muestra esto
failed: Error during WebSocket handshake: Unexpected response code: 502Aquí está mi docker-compose.yml
version: '3' services: nginx: image: nginx command: nginx -g 'daemon off;' ports: - "1010:80" volumes: - ./config/nginx/nginx.conf:/etc/nginx/nginx.conf - .:/makeup links: - web web: build: . command: /usr/local/bin/circusd /makeup/config/circus/web.ini environment: DJANGO_SETTINGS_MODULE: MakeUp.settings DEBUG_MODE: 1 volumes: - .:/makeup expose: - '8000' - '8001' links: - cache extra_hosts: "postgre": 100.73.138.65Nginx:
server { listen 80; server_name thelab518.cloudapp.net; keepalive_timeout 15; root /makeup/; access_log /dev/stdout; error_log /dev/stderr; location /api/stream { proxy_pass http://web:8001; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_redirect off; 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-Host $server_name; } location / { try_files $uri @proxy_to_app; } location @proxy_to_app { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Host $server_name; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://web:8000; }Y el archivo web.ini de circusd:
[watcher:web] cmd = /usr/local/bin/gunicorn MakeUp.wsgi:application -c config/gunicorn.py working_dir = /makeup/ copy_env = True user = www-data [watcher:daphne] cmd = /usr/local/bin/daphne -b 0.0.0.0 -p 8001 MakeUp.asgi:channel_layer working_dir = /makeup/ copy_env = True user = root [watcher:worker] cmd = /usr/bin/python3 manage.py runworker working_dir = /makeup/ copy_env = True user = www-dataComo se indica bastante explícitamente en el manual fino , para ejecutar Canales correctamente, debe tener un servidor de aplicaciones dedicado que implemente el protocolo ASGI, como el daphne suministrado.
Todo el modelo de ejecución de Django se ha cambiado con Canales, de modo que hay "servidores de interfaz" separados que se encargan de recibir y enviar mensajes, por ejemplo, WebSockets o HTTP o SMS, y "servidores de trabajo" que ejecutan el código real (potencialmente en un servidor diferente o VM o contenedor o...). Los dos están conectados por una "capa de canal" que transporta mensajes y responde de un lado a otro.
La implementación actual proporciona 3 capas de canales que hablan ASGI entre un servidor de interfaz y un servidor de trabajo:
Los configuras como lo haces para BASES DE DATOS:
CHANNEL_LAYERS = { "default": { "BACKEND": "asgi_redis.RedisChannelLayer", "ROUTING": "my_project.routing.channel_routing", "CONFIG": { "hosts": [("redis-channel-1", 6379), ("redis-channel-2", 6379)], }, }, } Por supuesto, esto significa que la configuración de su docker tiene que cambiar y agregar uno o más servidores de interfaz en lugar de, o además de, nginx (incluso si, en ese caso, deberá aceptar conexiones websocket en un puerto diferente con todos los problemas posibles conectados) y, muy probablemente, una instancia de redis conectándolos a todos.
Esto a su vez significa que hasta que circus y nginx puedan admitir ASGI, no será posible usarlos con canales django, o que este soporte solo será para la parte http normal de su sistema.
Puede encontrar más información en la sección Implementación de la documentación oficial .
Parece que daphne en el puerto 8001 e intentaste exponer los puertos 8000 y 8001 en docker-compose. El puerto 8000 no apunta a ningún servidor ( daphne está en 8001). En su nginx, configure el proxy en los puertos 8001 y exponga solo el puerto 8001 en docker-compose.
Creé un ejemplo simple de cómo se puede configurar en github donde tengo un proxy para servidores asgi y wsgi, pero puede usar solo el servidor asgi:
El nginx:
upstream app { server wsgiserver:8000; } upstream ws_server { server asgiserver:9000; } server { listen 8000 default_server; listen [::]:8000; client_max_body_size 20M; location / { try_files $uri @proxy_to_app; } location /tasks { try_files $uri @proxy_to_ws; } location @proxy_to_ws { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_redirect off; proxy_pass http://ws_server; } location @proxy_to_app { proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Url-Scheme $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://app; } }El docker-compose.yml:
version: '2' services: nginx: extends: file: docker-common.yml service: nginx ports: - 8000:8000 volumes: - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf volumes_from: - asgiserver asgiserver: extends: file: docker-common.yml service: backend entrypoint: /app/docker/backend/asgi-entrypoint.sh links: - postgres - redis - rabbitmq expose: - 9000 wsgiserver: extends: file: docker-common.yml service: backend entrypoint: /app/docker/backend/wsgi-entrypoint.sh links: - postgres - redis - rabbitmq expose: - 8000