Deployment of ASGI and WSGI

I’m sorry if my post is a bit confusing - I’m still new to Linux deployment.

I have a VPS running Debian. I have set up my Django project and everything is running fine. Now I’m using the following configuration, but it’s not working.

What is not working? Both the connection of my websocket results in a 404 not found, as well as every request to an HTTP endpoint which results in internal failure.

I use Django Ninja and Django Channels, as well as Nginx as server and Gunicorn and Uvincorn for my WSGI and ASGI.

Thank you very much for your help!

Configuration:

// projectone.conf (nginx)
upstream projectone_app_server {
        server unix:/webapp/projectone_backend/run/gunicorn.sock fail_timeout=0;
}

server {
        server_name mydomain.com;

        access_log /webapp/logs/access.log;
        error_log /webapp/logs/error.log;

        location /static/ {
                alias /webapp/projectone_backend/static/;
        }

        location /media/ {
                alias /webapp/projectone_backend/media/;
        }

        location / {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

                proxy_set_header Host $http_host;

                proxy_redirect off;

                if (!-f $request_filename) {
                        proxy_pass http://projectone_app_server;
                }
        }

        location /ws/ {
                proxy_pass http://projectone_app_server;
                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;
        }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/mydomain.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 = mydomain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


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


}



// gunicorn_start
#!/bin/bash

NAME='projectone'
DJANGODIR=/webapp/projectone_backend/
SOCKFILE=/webapp/projectone_backend/run/gunicorn.sock
USER=projectoneuser
GROUP=webapp
NUM_WORKERS=3
DJANGO_SETTINGS_MODULE=projectone.settings
TIMEOUT=120

cd $DJANGODIR
source /webapp/env/bin/activate
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DJANGODIR:$PYTHONPATH

RUNDIR=$(dirname $SOCKFILE)
test -d $RUNDIR || mkdir -p $RUNDIR

exec ../env/bin/gunicorn projectone.asgi:application \
--name $NAME \
--workers $NUM_WORKERS \
--timeout $TIMEOUT \
--user=$USER --group=$GROUP \
--bind=unix:$SOCKFILE \
--log-level=debug \
--log-file=-



// Supervisord project config file
[program:projectone]
command = /webapp/env/bin/gunicorn_start
user = projectoneuser
stdout_logfile = /webapp/logs/supervisor.log
redirect_stderr = true
environment=LANG=en_US.UTF-8,LC_ALL=en_US.UTF-8

First item is that gunicorn isn’t going to handle websocket connection upgrades. Your /ws/ url should be forwarding to a Daphne / uvicorn / asgi service. Your gunicorn instance should be handling wsgi only.

Also, if you’re separating the handling of those two, there are usually changes that need to be made to the asgi.py file for that. Please post that file.

Second, depending upon the rest of your configuration, this setting is probably not going to handle traffic to your site. (Unless you’re the owner of mydomain.com, which I kind of doubt.)

You might want to see the thread at Django Websockets deployment issue for a more complete example of a functional environment. (There are other threads here as well showing working configurations.)

Thanks Ken. I didn’t want to show my domain here (that’s why I’ve written “mydomain.com”).

This is my asgi file:

"""
ASGI config for projectone 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

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

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "projectone.settings")
django.setup()

# Initialize Django ASGI application early to ensure the AppRegistry
# is populated before importing code that may import ORM models.
application = get_asgi_application()

import calendar_.routing
from projectone.jwt_auth_middleware import JwtAuthMiddleware

application = ProtocolTypeRouter(
    {
        "http": application,
        "websocket": AllowedHostsOriginValidator(
            JwtAuthMiddleware(URLRouter(calendar_.routing.websocket_urlpatterns))
        ),
    }
)