Deploying Django with Gunicorn,Nginx & Supervisor

In this tutorial we will explore how to deploy our django project to a production server. Below are the general steps.

  • Serving Django Project with gunicorn
  • Setup nginx conf in /etc/nginx/sites-available/myproject.conf
  • Create a symbolic link in /etc/nginx/sites-enabled
  • Restart nginx to see 501
  • Create a myproject.supervisor.conf file in /supervisor/conf.d/ directory
  • Run supervisorctl

Using Gunicorn to Serve Django during development

Gunicorn is a wsgi server that is used to serve web apps during production. We
can also use it to test our django project inplace of the runserver that comes with django.

# Used in development
python manage.py runserver
# Used to replace runserver in production
export PYTHON_PATH=myproject
export DJANGO_SETTINGS_MODULE=myproject.settings
gunicorn --workers 3 --bind 0:8000 myproject.wsgi:application

Setting Up Nginx

  • Nginx is used to serve static files and act as load balance and reverse proxy
  • Most important to notice is the sites-available and sites-enabled directory
sudo apt update
sudo apt install -y nginx
systemctl status nginx
  1. Configure Nginx Project for Django
sudo su
cd /etc/nginx/sites-available/
touch myproject.conf
Sample File
server {
    listen 80;
    server_name myproject.com;
    client_max_body_size 2G;
    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/ubuntu/env_myproject/myproject;
    }
    location / {
        include proxy_params;
        proxy_pass http://localhost:8000;
    }
}
Another example
server {
    listen 80;
    server_name myproject.com; or ip address

    location /static/ {
        alias /home/jcharis/Documents/myproject/static/;
    }
    location  /media/ {
        alias /home/jcharis/Documents/myproject/media/;
    }
    location / {
        proxy_pass http://myproject.com:8000;
    }
}
  1. Link the site-available to site-enabled
 sudo ln -s /etc/nginx/sites-available/myproject.conf /etc/nginx/sites-enabled/myproject.conf
  1. Restart nginx
# Test if nginx works with the configurations
sudo nginx -t

# Start Nginx
sudo systemctl restart nginx

# Check Status
sudo systemctl status nginx

If you see a 502 or 504 page it means it works now we need to run gunicorn

Running Gunicorn

There are several ways to run gunicorn uninterruptedly.
– using systemd
– using journalctl
– using supervisor

In our case we will place our commands inside our supervisor conf file after installing supervisor

  1. Install supervisor
sudo apt update
sudo apt-get install -y supervisor

# Or with pip
pip install supervisor
  1. Configure Supervisor
cd /etc/supervisor/conf.d/
touch myproject-supervisor.conf
  1. Place the commands and directory that you want supervisor to run in the conf file (myproject-supervisor.conf)
[inet_http_server]
port=0.0.0.0:9001
username = user
password = 123
[program:myproject]
directory=/home/ubuntu/env_myproject/myproject
command=/home/ubuntu/env_myproject/bin/gunicorn --workers 3 --bind 0:8000 myproject.wsgi:application
autostart=true
autorestart=true
stderr_logfile=/var/log/myproject/gunicorn.err.log
stdout_logfile=/var/log/myproject/gunicorn.out.log

  1. Create the directory for the logs for the stderr and stout
  2. Start Supervisor
sudo supervisorctl reread
sudo supervisorctl update

# check status
sudo supervisorctl status

# Restart all programs in supervisor.conf
sudo supervisorctl restart all 

# Reload
sudo supervisorctl reload

Fixing Errors

  1. nginx.service failed
jcharis@jcharis-vivobook:/etc/nginx/sites-available$ sudo systemctl restart nginx
Job for nginx.service failed because the control process exited with error code.
See "systemctl status nginx.service" and "journalctl -xeu nginx.service" for details.

Check the logs to see the error

2023/03/10 03:48:27 [emerg] 50614#50614: bind() to 0.0.0.0:80 failed (98: Unknown error)
2023/03/10 03:48:27 [emerg] 50614#50614: bind() to [::]:80 failed (98: Unknown error)
2023/03/10 03:48:27 [emerg] 50614#50614: still could not bind()

Check if there are no services running on the same port since you cant have two servers running on the same port eg nginx and apache2

jcharis@jcharis-vivobook:/etc/supervisor/conf.d$ sudo netstat -plunt | grep 80
[sudo] password for jcharis: 
tcp        0      0 0.0.0.0:8000            0.0.0.0:*               LISTEN      36831/python        
tcp6       0      0 :::80                   :::*                    LISTEN      1593/apache2

Stop the apache2

sudo service apache2 stop

Restart nginx

sudo systemctl restart nginx

Thanks For Your Attention

Jesus Saves
  • Jesse E.Agbe(JCharis)

Leave a Comment

Your email address will not be published. Required fields are marked *