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