Host django application using gunicorn & nginx

5 min read

In this article, we'll look at how to serve django applications in a production environment using nginx and gunicorn. 

Django is a very capable web framework that comes with a server that can speed up development. This development server is not suitable for production and is not scalable. Nginx can be used as a reverse proxy and as a web server to serve static files, but we need to configure Gunicorn to gain better scalability. Let's start now. 

Step 1 - Installing python and nginx

sudo apt update
sudo apt install python3-pip python3-dev nginx

 

Step 2: Setting up a virtual Python environment 

sudo pip3 install virtualenv

With this, a virtual environment package for Python will be installed. Let's construct a virtual environment inside the project directory that will house our Django application.

virtualenv env

The creation of a virtual environment with the name env. Let's turn on this imaginary setting:

source env/bin/activate

Step 3 - Installing django and gunicorn

pip install django gunicorn

django and gunicorn are now set up in our virtual environment.

Step 4 - Setting up our Django project

At this point, you have the option of creating a new Django project or copying your current one into the coreproject folder, as illustrated below:

mkdir ~/coreproject
cd ~/coreproject
django-admin startproject core .

Include your IP address or domain name in the settings.py file's ALLOWED_HOSTS variable.

Run any migrations you need to in the following manner:

~/coreproject/manage.py makemigrations
~/coreproject/manage.py migrate

Run the following commands to test this sample project:

sudo ufw allow 8000

This permits port 8000 to pass across the firewall, opening it. Let's launch our Django development server to evaluate the current configuration:

~/coreproject/manage.py runserver 0.0.0.0:8000

Step 5 - Configuring gunicorn

Let's use the following commands to gauge Gunicorn's suitability for our application:

gunicorn --bind 0.0.0.0:8000 core.wsgi

Gunicorn should now be running on port 8000. Returning to the browser will allow us to test our application. Checking out http://<ip-address>:8000 displays the following page:

For gunicorn, let's make a system socket file right away:

sudo vim /etc/systemd/system/gunicorn.socket

Copy the content below, then save the document.

[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/run/gunicorn.sock

[Install]
WantedBy=sockets.target

For Gunicorn, we will then construct a service file.

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

Copy and paste the following text into this file:

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

[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/coreproject/core
ExecStart=/home/env/bin/gunicorn \\
          --access-logfile - \\
          --workers 3 \\
          --bind unix:/run/gunicorn.sock \\
        core.wsgi:application

[Install]
WantedBy=multi-user.target

Now let's launch and activate the gunicorn socket.

sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket

Step 6 - Configuring Nginx as a reverse proxy

Use this command to create a Nginx configuration file.

sudo vim /etc/nginx/sites-available/coreproject

Put the following content inside the newly generated file.

server {
    listen 80;
  server_name www.example.org;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
      root /home/coreproject/;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/run/gunicorn.sock;
    }
}

Utilise the following command to activate the configuration:

sudo ln -s /etc/nginx/sites-available/coreproject /etc/nginx/sites-enabled/

nginx should be restarted to make the modifications effective.

sudo systemctl restart nginx