Django Channel Connection Refused in Production

Hi,

I’m currently implementing Django Channels for asynchronous communication. The setup works flawlessly on my local environment, but when deployed in production (Docker container), I encounter a “connection refused” error for WebSocket connections.

Could you please review my configuration and advise on any potential issues? Your insights would be greatly appreciated.

asgi.py
"""
ASGI config for sewts_jupiter_cloud_backend 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/5.0/howto/deployment/asgi/
"""

import os

# from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
# from channels.security.websocket import AllowedHostsOriginValidator
from django.core.asgi import get_asgi_application

import channel.urls

setting_evironment = os.getenv('ENVIRONMENT')
os.environ.setdefault('DJANGO_SETTINGS_MODULE',
                      f'sewts_jupiter_cloud_backend.settings.{setting_evironment}')

application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    # TODO: apply allowed host check here
    "websocket": URLRouter(channel.urls.websocket_urlpatterns)

})



setting
ALLOWED_HOSTS=192.168.108.76,ws://192.168.108.76
CORS_ALLOWED_ORIGINS=http://192.168.108.76:8080,http://192.168.108.76:8001,http://192.168.108.76:8000

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels.layers.InMemoryChannelLayer",  # This uses an in-memory layer
        "CONFIG": {},
    },
}

INSTALLED_APPS = [
    'daphne',
    'channels',
-----




ERROR on browser

Welcome @muhammad-sewts !

We’re going to need to know a lot more details about your project and your deployment environment.

  • What versions of Django, Channels, and Python are you using?

  • What web server are you using?

    • How is it configured for handling the web sockets?
  • How are you running Daphne? (What is the command being used to start it?)

  • What is the JavaScript code that you are using to connect to the websocket?

This is bad. Change to an appropriate channel layer (redis).

This all is just a starting point, we’re likely to have more questions based upon your answers to these.

  • Versions
    • Python 3.10.15
    • Django 5.0.6
    • Channels 4.1.0
  • I install Daphne 4.1.2 But i didn’t add any other configuration or something, Im pretty new to the servers knowledge so I dont have idea. I tried to run the server by both ways python manage.py server and gunicorn ..... but it didn’t worked.
  • I’m not doing anything with daphne since it was working fine without it on localhost. ]
  • Just FYI I have rest interface as well in application so I need channles communication for logs transfer from backend to frontend.
  • I’m using Vue3 on frontend and following code im using for channel connection.
// https://vueuse.org/core/useWebSocket/
const { status, data, send, open, close } = useWebSocket(
  WEB_SOCKET_URL + `log/device/${route.params.deviceId as string}/`,
  {
    autoReconnect: true,
    onMessage(ws, event) {
      try {
        const message = JSON.parse(event.data)
        messages.value.push(message.message)
      } catch (error) {
        return
      }
    }
  }
)

I want to try out InMemoryChannelLayer for now only until we will deploy our application for commercial use. I don’t know if it has anything to do with connection between frontend and backend. We will use redis or something else in future but for now we dont want to do that if it’s possible without that.

Nope. Don’t do this. Redis is trivial to install and for your testing purposes, will not need any custom configuration.

This is not correct. If you look at the startup messages that runserver is giving you, you’ll see that it’s starting daphne to handle the websockets.

See the docs for runserver - never use this in a deployment / production environment, and gunicorn is a wsgi server - it doesn’t do async.

Yes, there’s a lot that needs to be done to get this all working, and it can be confusing the first time. (But it is possible.)

Start with reviewing the docs at Deploying — Channels 4.2.0 documentation

Also, if you search the forum here for “channels nginx” or “websockets nginx”, you’ll see a number of threads - many with the actual configuration paragraphs - showing deployment-related configurations.

Oh thank you so much for your comment, I will look into all your comments detail and related threads as well. Thanks again!

I made all those changes and still see the same issue, I can even connect with socket channel when i spin container locally but when i do on IPC that have static IP to make it available over the same network i get the same error, is it something wrong with IPC configurations or i need to change the settings.

command to start the server in docker-compose file:
daphne sewts_jupiter_cloud_backend.asgi:application -b 0.0.0.0 -p 8000

 INSTALLED_APPS = [
    'daphne',
    'channels',
....

nginx.conf

# Ref: https://medium.com/@agalliani/tutorial-deploying-a-vite-vue-js-app-with-custom-nested-paths-using-docker-and-nginx-1fa8cf4b1d93
worker_processes 4;

events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    server {
        listen 8080;
        root /usr/share/nginx/html;

        location / {
            try_files $uri $uri/ /index.html;
        }
        
        # Proxy configuration for Django WebSocket connections
        location /ws/ {
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_redirect off;
            proxy_pass http://192.168.108.76:8000/ws/;

        }
    }
}

What is this “IPC” that you are referencing? (I’m aware of a couple different definitions of that acronym and don’t know what you’re refering to here.)

What operating system are you running this on? Is the listening port open and accessible from the network?

When you’re trying to connect, what are the nginx and daphne logs showing? (The connection attempts should be showing up in both logs.)

Note: If you’re proxying this through nginx, then there’s no need for daphne to listen on all interfaces. It’s better if you have it listening to localhost only. (That means your nginx proxy should be forwarding the requests to 127.0.0.1.)

Think of IPC as a regular PC setup. Instead of using localhost, I’m attempting to run the container on a network IP so it’s accessible within the same network.

On Ubuntu, there’s no indication of socket connection requests; I only see details about HTTP requests.

A websocket connection is an HTTP request.

With nginx serving as a proxy, nginx will log the websocket connection after the websocket has closed. You will see it (by default) in the access.log file. If you’re not seeing the requests in the log file, then you may want to use something like tcpdump or wireshark to look at the request traffic.

Again, with nginx as a proxy, people don’t connect to daphne. They connect to nginx. Nginx proxies the connection through to daphne, so there’s no need for daphne itself to be visible on the local network.

Thank you for mentioning that, Finally I just used Redis and it works fine and I also remove the proxy for now, Since I don’t need it. But I learn new things from your comments so Thanks again!