Can not connect to websocket using django-channels , nginx on docker as services Can not connect to websocket using django-channels , nginx on docker as services nginx nginx

Can not connect to websocket using django-channels , nginx on docker as services


As quite explicitly stated in the fine manual, to successfully run Channels you need to have a dedicated application server implementing the ASGI protocol, such as the supplied daphne

The entire Django execution model has been changed with Channels, so that there are separate "interface servers" taking care of receiving and sending messages over, for example, WebSockets or HTTP or SMS, and "worker servers" that run the actual code (potentially on a different server or VM or container or...). The two are connected by a "Channel layer" that carries messages and replies back and forth.

The current implementation supplies 3 channel layers that talk ASGI between an interface server and a worker server:

  • An In-memory channel layer, used mainly for running the test server (it's single process)
  • An IPC based channel layer, usable to run different workers on the same server
  • A redis based channel layer, that should be used for heavy production sites, able to connect interface servers to multiple worker servers.

You configure them like you do for DATABASES::

CHANNEL_LAYERS = {    "default": {        "BACKEND": "asgi_redis.RedisChannelLayer",        "ROUTING": "my_project.routing.channel_routing",        "CONFIG": {            "hosts": [("redis-channel-1", 6379), ("redis-channel-2", 6379)],        },    },}

Of course this means that your docker config has to change and add one or more interface servers instead of, or in addition to, nginx (even if, in that case, you'll need to accept websocket connections on a different port with all the connected possible problems) and, quite likely, an instance of redis connectin all them.

This in turn means that until circus and nginx can support ASGI, it won't be possible to use them with django-channels, or that this support will only be for the regular http part of your system.

You can find more info in the Deploying section of the official documentation.


It looks that you stared daphne on port 8001, and trying to expose port 8000 and 8001 in docker-compose. The port 8000 is not pointing to any server (daphne is on 8001). In your nginx please set proxy to 8001 ports and expose only port 8001 in docker-compose.

I have created a simple example how it can be set on github where I have proxy to asgi and wsgi servers, but you can go with only asgi server:

The 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;    }}

The 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