In this post, we will set up a async Django project online using Daphne and NGINX. The current post is based on a few hours or research within the past few years. This configuration will be compatible with async events in Django.

This diagram represents the relationship between technologies we will use in this post. I made it very simple for you to focus on the important bits of this post.
Quick reminder before starting
Synchronous basically means that you can only execute one thing at a time. Asynchronous means that you can execute multiple things at a time and you don’t have to finish executing the current thing in order to move on to next one.
For this post, you can use Python 3.7 or higher.
Personally, I used a VPS (Virtual Private Server) provided by OVH for many years. You can have a look at their offers here.
Django project
Clone Django project
git clone --single-branch --branch step1 git@github.com:blancheta/django-notifications-example.git django_async_notifications
# Install dependencies in virtualenv
cd <project-path>
pip install --upgrade virtualenv
virtualenv -p python3 venv
source venv/bin/activate
pip install -r requirements.txt
Daphne
Daphne does the same job than Gunicorn excepted that it can also handle asynchronous connections.
Test the daphne command to check that the Django project can start well from daphne.
cd /<project-path>
venv/bin/daphne -u /tmp/django_async_notifications.sock --proxy-headers django_async_notifications.asgi:application
For the result:
Starting server at unix:/tmp/django_async_notifications.sock
HTTP/2 support not enabled (install the http2 and tls Twisted extras)
Configuring endpoint unix:/tmp/django_async_notifications.sock
Supervisor
Supervisor is a process control system. It helps to monitor and control processes in UNIX like environments.
sudo apt-get install supervisor
Copy/Paste the content of this file in a new config file into /etc/supervisor/conf.d/
[program:django_async_notifications]
directory=/<project-path>
command=/<project-path>/venv/bin/daphne -u /tmp/django_async_notifications.sock --proxy-headers django_async_notifications.asgi:application
autostart=true
autorestart=true
redirect_stderr=true
startretries=10
environment=PATH="/<project-path>/venv/bin",LANG="en_US.UTF-8", LC_ALL="en_US.UTF-8", LC_LANG="en_US.UTF-8"
stderr_logfile=/var/log/django_async_notifications/supervisor_error.log
Now, let’s make visible the new config for Supervisor.
sudo supervisorctl reread
# Now the process manager should be running
sudo supervisorctl status django_async_notifications
To continue, you need a domain name redirecting to your VPS.
Domain name server
A quick way to create a free domain name is to use noip.
Then, redirect the domain name to your vps ip.

Try now to ping your dns to make sure. It is redirecting requests to your VPS ip.
In your Django project settings
, add your domain name in ALLOWED_HOSTS
.
For the request to be allowed to reach NGINX, you will need to allow the port 80 for your VPS Firewall.
sudo ufw allow 'Nginx Full'
Nginx
sudo apt-get install nginx
Save the following config file into /etc/nginx/sites-available/django_async_notifications.conf.
Replace example.com by the domain name created.
# django_async_notifications.conf
# the upstream component nginx needs to connect to
upstream django_async_notifications {
server unix:/tmp/django_async_notifications.sock; # for a file socket
}
# redirect unsafe request to safe request
server {
listen 80;
server_name django-notif.ddns.net;
return 301 https://$server_name$request_uri;
}
# redirect safe request on domain to safe sub domain request
server {
listen 443;
server_name django-notif.ddns.net;
# access_log /var/log/django_async_notifications/nginx.access.log;
# error_log /var/log/django_async_notifications/nginx.error.log;
charset utf-8;
# max upload size
client_max_body_size 75M; # adjust to taste
# Django media
location /media/ {
alias /var/www/django_async_notifications/static/images/; # your Django project's media files - amend as required
}
location /static/ {
alias /var/www/django_async_notifications/static/; # your Django project's static files - amend as required
}
# Finally, send all non-media requests to the Django server.
location / {
try_files $uri @proxy_to_app;
}
location @proxy_to_app {
proxy_pass http://django_async_notifications;
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;
}
}
Create a symbolic link to enable your conf.
ln -s /etc/nginx/sites-available/django_async_notifications.conf /etc/nginx/sites-enabled/django_async_notifications.conf
sudo service nginx restart
Now put your dns in the url. Should have something similar to this.

Getting a HTTPS Certificate
I prefer to share with you this well written post rather than just copy/pasting the precious content. https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-18-04
sudo certbot --nginx -d your.domaine.name
And choose option 2 which will add automatically the certificate to your nginx config.
Clean your cache before retrying or go to your domain via an other browser
You should now see the lock.
Congrats you website is now secure!
In the next post, we will add a bar with a notification bell to our project.

To know more about me: https://www.upidev.com/a-propos/ [FR version]
Sources:
- https://stackoverflow.com/questions/55726610/django-ssl-redirection-on-heroku-too-many-redirects
- https://channels.readthedocs.io/en/latest/
- https://serverfault.com/questions/331256/why-do-i-need-nginx-and-something-like-gunicorn
- https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-18-04
- https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-16-04
- https://docs.djangoproject.com/fr/3.1/topics/async/#envvar-DJANGO_ALLOW_ASYNC_UNSAFE