Django with Nginx + Uvicorn - Configuration issues

Hi,

I am trying to run a Django website with channels activated to use the websocket. Everything is working fine when using runserver, but things are getting spicy while switching to Nginx + Uvicorn.

here is my /etc/systemd/system/gunicorn.service


[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
User=root
Group=www-data
WorkingDirectory=/home/myapp/
ExecStart=/usr/local/bin/gunicorn -w 1 -k uvicorn.workers.UvicornWorker --timeout 300    --bind unix:/home/myapp/myapp.sock myapp.asgi:application


[Install]
WantedBy=multi-user.target

here is my /etc/systemd/system/gunicorn.socket

[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/home/myapp/myapp.sock

[Install]
WantedBy=sockets.target

and here is my /etc/nginx/sites-available/myapp

server {
    listen 80;
    server_name myapp.box 10.42.0.1;
    
    
    location = /favicon.ico { access_log off; log_not_found off; }
    location ~ ^/static {
        autoindex on;
        root /home/myapp;
    }

    location ~ ^/ {
        include proxy_params;
        proxy_pass http://unix:/home/myapp/myapp.sock;
    }
    location @proxy_to_app {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_buffering off;
        
        proxy_pass http://unix:/home/myapp/myapp.sock;
    }
}

Nginx is running, the socket and gunicorn an issue with gunicorn showing the below error message.

Jul 07 11:14:11 hostname gunicorn[1825]:   File "/usr/local/lib/python3.8/dist-packages/django/conf/__init__.py", line 76, in __getattr__
Jul 07 11:14:11 hostname gunicorn[1825]:     self._setup(name)
Jul 07 11:14:11 hostname  gunicorn[1825]:   File "/usr/local/lib/python3.8/dist-packages/django/conf/__init__.py", line 57, in _setup
Jul 07 11:14:11 hostname  gunicorn[1825]:     raise ImproperlyConfigured(
Jul 07 11:14:11 hostname  gunicorn[1825]: django.core.exceptions.ImproperlyConfigured: Requested setting INSTALLED_APPS, but settings are not configured. You must either define the envir>
Jul 07 11:14:11 hostname  gunicorn[1825]: [2021-07-07 11:14:11 +0800] [1825] [INFO] Worker exiting (pid: 1825)
Jul 07 11:14:12 hostname  gunicorn[1822]: [2021-07-07 11:14:12 +0800] [1822] [INFO] Shutting down: Master
Jul 07 11:14:12 hostname  gunicorn[1822]: [2021-07-07 11:14:12 +0800] [1822] [INFO] Reason: Worker failed to boot.

When I am trying to reach my website, I have the page “Welcome to nginx!” and impossible to get the pages from my site (logical as Gunicorn can’t get Django running)

I also attach my /home/myapp/asgi.py file

"""
ASGI config for myapp 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/3.0/howto/deployment/asgi/
"""
import os
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
import myapp.routing
import MyApp.routing

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myapp.settings')
django.setup()

application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    "websocket": AuthMiddlewareStack( URLRouter( MyApp.routing.websocket_urlpatterns ) ),
    # Just HTTP for now. (We can add other protocols later.)
})

Anyone would get an idea of what is going on and where I am missing something?

thank you,

Tibibs

What’s your directory structure for you application within /home/myapp?

If it’s something like:

/home/myapp
    myproject
        myapp
            asgi.py
            settings.py
            ...
        myapp2
        myapp3

then your WorkingDirectory should probably be /home/myapp/myproject.

Hi,

The structure is as below

/home/myapp/
	manage.py
	myapp.sock
	myapp/
		asgi.py
		wsgi.py
		settings.py
		urls.py
	MyApp/
		views.py
		urls.py
		templates/
	MyApp2/
		views.py
		urls.py
		templates/

I have renamed it in my files to be more generic, I admit the choice of the naming is not the smartest.
You need to consider the MyApp being case sensitive (lowercase is project name, Capitalized is the app)

My first inclination would be to run gunicorn from the command line with --log-level debug, to see if there’s any additional useful information provided.

(Also, it appears you could possibly encounter a permissions issue with that socket file. You’re also running gunicorn as root - something I never recommend.)

Ok, I have managed to fix it.
in the asgi.py, I am importing some external modules, and settings.py must be loaded first.
I have added the 2 below lines on top of my asgi.py

import django
django.setup()

before qll the imports, and it seems to work so far

1 Like