nginx + gunicorn + Django = Production-ready

> How to deploy a django project using gunicorn and nginx. Also to add ssl certificate from certbot

Rishabh Umrao
3 min readMar 2, 2021

Django gives a local server but this is not a recommended solution for production environment… For this we’ll use nginx+gunicorn to make it more fault tolerant and robust.

How to create your own django project?

  • Create a directory and a virtual environment in it
mkdir dummyproj && cd dummyproj
python3 -m venv newenv
source newenv/bin/activate
  • Install Django.
pip3 install Django
  • Create and start your project
django-admin.py startproject hello

cd hello/

python manage.py runserver 0.0.0.0:8000

This will run your test project. If you are not testing it locally then you’ll have to allow hosts to connect to this project by editing hello/settings.py file.

ALLOWED_HOSTS = ['*']

Now you have your django project running successfully.

Making it production ready…

Django has a single threaded testing server which can not meet the requirements of the production environment. So we’ll use a dedicated service called gunicorn.

  • Install gunicorn in your virtual environment
pip3 install gunicorn
  • check if it works fine with the django project
gunicorn hello.wsgi:application --bind 0.0.0.0:8000
  • Open another terminal and check if you can access it from the public IP on port 8000
  • Install nginx on your machine (I am using a debian based system so this worked for me fine.)
  • Once nginx and gunicorn are ready, we can make our django code production ready.

Let’s first gather all the details we’ll need to connect everything together.

  • Nginx will forward the request to gunicorn, so we need a proxy_pass which points to gunicorn (Basically points to gunicorn socket)
  • gunicorn will request the data from django project (via socket). And gunicorn is present inside the virtual environment here.

Let’s begin with connecting the dots.

First, I’ll create a gunicorn service file that can use socket to connect to django project and make requests to it.

sudo vim /etc/systemd/system/gunicorn-hello.service

And add the below lines to it.

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

[Service]
User=ayedaemon ## User who has permissions to the WorkingDirectory
Group=www-data
## Directory where the project resides
WorkingDirectory=/home/ayedaemon/dummyproj/

## What command will start by this service
ExecStart=/home/ayedaemon/dummyproj/newenv/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/home/ayedaemon/dummyproj/hello.sock\
hello.wsgi:application

[Install]
WantedBy=multi-user.target

(Note) These values might change as per your project structure

Once a socket is created. Check it using curl.

curl --unix-socket /home/ayedaemon/dummyproj/hello.sock localhost

Now you have a gunicorn --> Django connection established. Let's go for Nginx --> gunicorn now.

Create a sites file for nginx (configuration file).

sudo vim /etc/nginx/sites-available/helloproj.conf

Now add below configuration to it.

server
listen 1234;
server_name <your domain name>; ## Add your domain name or ip on which it'll be hosted

location /static/ {
alias /home/ayedaemon/dummyproj/hello/static/;
}

location / {
include proxy_params;
proxy_pass http://unix:/home/ayedaemon/dummyproj/hello.sock;
}
}

make a soft link of this file in sites-available.

sudo ln -s /etc/nginx/sites-available/helloproj.conf /etc/nginx/sites-enabled

Restart the servers and reload all configurations.

sudo systemctl daemon-reload
sudo systemctl restart gunicorn-hello.service
sudo systemctl restart nginx

How to install certbot ssl certificate?

This is very simple and straight forward thing to do. Thanks to certbot for all the automation they have done. There are 3 simple steps to be followed.

  1. Install certbot for your system.
  2. Configure certbot to install certificate for your site.
  3. Check it.

You can use this to get all the instructions to follow.

--

--