Using websockets with HTTPS/WSS

Hello everyone,
after the great help from you, I finishid building my simple web chat app using Django channels.

Now I wanted to move to a production state. I have already set up the communication between Django and Nginx with uWSGI. I got a SSL certificate installed by certbot.
When testing my chat app I got this error in the browser:
NS_ERROR_WEBSOCKET_CONNECTION_REFUSED
from line 4 in my websocket.js file, which reads

const webSocket = new WebSocket(
    'wss://' + window.location.host + '/ws/chat/'
);

This is my nginx configuration file:

# The upstream component nginx needs to connect to
upstream django {
    server unix:///home/production/myproject/myproject.sock;
}

# Configuration of the server
server {
    server_name myproject.com;
    charset     utf-8;
    # max upload size
    client_max_body_size 75M;
    # Django media and static files
    location /media  {
        alias /home/production/myproject/media;
    }
    location /static {
        alias /home/production/myproject/static;
    }

    # Send all non-media requests to the Django server
    location / {
        uwsgi_pass  django;
        include     /home/production/myproject/uwsgi_params;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/myproject.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/myproject.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = myproject.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen      80;
    server_name myproject.com;
    return 404; # managed by Certbot
}

I have already tried adding this, which I found after some research, or some other form of this to the configuration but that didn’t help.

    # WebSocket handling
    location /ws/ {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_redirect off;
        proxy_pass http://127.0.0.1:8001/ws/;
    }

How do I get this to work? I am happy to give more information if needed.
Thanks in advance

How are you running Daphne for this connection? (What’s the command line you are using for it?)

Sorry, but I don’t really get your question. I just installed daphne and added to the installed apps. I tried adding what I previously mentioned to the Nginx config and running the webserver. Do I need to do anything else with Daphne? (I found little to nothing regarding the wss setup on the internet)

The “wss” vs “ws” portion doesn’t matter here. Nginx is your TLS endpoint, so what gets proxied through is straight http.

However, you’re telling nginx to forward this traffic through to something listening on port 8001.

What do you have running that is listening on port 8001, that is capable of serving websockets? (I use Daphne for this.)

Okay, now I get it.
Well…
I run have Daphne installed aswell but haven’t done any configuration or anything. Everything worked like that without any problem when using normal ws.
It might sound silly (it probably is) but I found that on the internet and just expected it to work, since I there was not much more information. :sweat_smile:
What do I need to reconfigure/set up in order for wss to work then?

It’s covered in the docs at Deploying — Channels 4.0.0 documentation

Note: The issue has nothing to do ws vs wss, it’s an issue of getting it to work behind nginx.

You’re running uWSGI to run the Django app, you need to run Daphne to handle channels.

In a development environment, with Daphne installed, the runserver command is actually running Daphne. If you’re running channels already, you would see the output of the runserver command looks like this:

Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
August 30, 2024 - 15:16:28
Django version 5.0.7, using settings 'mpge_channels.settings'
Starting ASGI/Daphne version 4.1.2 development server at http://127.0.0.1:8000/
******** ^^^^^^^^^^^
Quit the server with CONTROL-C.

Makes sense. Thanks for pointing me in the right direction. I will look into that and try to set it up. I will let you know when I get it to work.

If you run into problems, we are here to help.

1 Like

I got it working!
I litterally just had to add what I previously mentioned to my nginx sites-available config and run this command:

daphne -p 8001 myproject.asgi:application

and it worked.
Channels and danphne is completely new for me (this was my first project with it) so I did not get that before.
Thanks again for your help!