Programming

Set Up Django with Postgres, Nginx, and Gunicorn on Ubuntu 22.04

In this article, we’ll explain how to set up Django with Postgres, Nginx, and Gunicorn on Ubuntu 22.04.

Django is a free and open-source, Python-based web framework that follows the model–template–views architectural pattern.  It comes with a development server to test your Python code in the local system. For production, We need a more secure and powerful web server.

In this demonstration, we will see how to set up python virtual environment and install Django and configure some components on Ubuntu 22.04. For database, we will install and configure PostgreSQL database. We will configure the Gunicorn application server to interface with our applications. We will install and configure Nginx to reverse proxy to Gunicorn. It will give us access to its security and performance features.

Prerequisites:

  • A Ubuntu 22.04 installed server
  • A root user access or non-root user with administrative privileges.
  • A valid domain name with pointed A record.

Set Up Django with Postgres, Nginx, and Gunicorn on Ubuntu 22.04

1. Update Server

First, keep the server up to date

sudo apt update && sudo apt upgrade -y

2. Install Packages

Here, we’ll install required packages. Like Python package manager pip , PostreSQL database, and Nginx.

sudo apt install python3-pip python3-dev python3-venv libpq-dev postgresql postgresql-contrib nginx -y

3. Configure PostgreSQL Database

Next, we will create a database and user for our Django project.

Log into an interactive Postgres session

sudo -u postgres psql

First, create a database for your project:

postgres=# CREATE DATABASE databasename;

Note: Replace the databasename as per your choice.

Next, create a database user for our project. Make sure to select a secure password:

postgres=# CREATE USER databaseuser WITH PASSWORD 'password';

Note: Replace the databaseuser as per your choice and use the strong password.

We’ll modify a few of the connection parameters for the user we just created. Django assumes that all databases use UTF-8 encoding. Using other encodings may result in unexpected behavior such as “value too long” errors from your database for data that is valid in Django. Django needs the following parameters for its database connections. For more information on this you can check the official documentation page.

postgres=# ALTER ROLE databaseuser SET client_encoding TO 'utf8';
postgres=# ALTER ROLE databaseuser SET default_transaction_isolation TO 'read committed';
postgres=# ALTER ROLE databaseuser SET timezone TO 'UTC';

Finally, we will grant privileges to the user we have created.

postgres=# GRANT ALL PRIVILEGES ON DATABASE databasename TO databaseuser;

Exit the PostgreSQL prompt

postgres=# \q

4. Create a Python Virtual Environment

Now, we will create a Python virtual environment.

First, upgrade the pip

sudo pip3 install --upgrade pip

Create a directory for our project:

sudo mkdir /var/www/django_project && cd /var/www/django_project

Change the owner and group of the directory. It is not good practice to set owner and group as a root.

sudo chown -R user:user ../django_project

Next, create a virtual environment using following command:

python3 -m venv env

Now, activate the virtual environment:

source env/bin/activate

Finally, install the Django, Gunicorn, and PostgreSQL required package using following command:

pip install django gunicorn psycopg2-binary

5. Create and Configure Django Project

django-admin startproject django_project /var/www/django_project

Note: Replace the project_name as per your choice.

Next, edit the setting.py and add your website name in ALLOWED_HOSTS and modify the database configuration.

nano django_project/settings.py

Find ALLOWED_HOST and add your website name:

ALLOWED_HOSTS = ['django.example.com', 'localhost', 'server_ip']

Note: Replace ‘server_ip’ with your server IP.

Find DATABASES and modify the values

DATABASES = {  
	'default': {     
	        'ENGINE': 'django.db.backends.postgresql_psycopg2',
		'NAME': 'databasename',
		'USER': 'databaseuser',
		'PASSWORD': 'password',
		'HOST': 'localhost',
	}
}

Add following lines in the end:

import os
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')

Save and close the file.

Now, we need to migrate the initial database schema to the PostgreSQL database.

python manage.py migrate

Next, gather all the static content into the directory

python manage.py collectstatic

6. Test the Django Development Server

If UFW is enabled, add the Django development server port using following command:

sudo ufw allow 8000/tcp

Start the Django server.

python manage.py runserver 0.0.0.0:8000

Navigate to your browser and enter your server IP following with 8000 port http://server_ip_or_domain_name.com:8000.

Set Up Django with Postgres, Nginx, and Gunicorn HostnExtra

Now stop the server. So, we can test Gunicorn.

7. Test Gunicorn

Next, we need to test the Gunicorn to check whether the Gunicorn can serve the Django or not. Run the following command:

gunicorn --bind 0.0.0.0:8000 django_project.wsgi

If everything is fine, navigate to your browser and enter your server IP following with 8000 port.

Now stop the Gunicorn server by pressing CTRL + C and deactivate the Python virtual environment.

deactivate

8. Creating systemd Socket and Service Files for Gunicorn

To implement a more robust way of starting and stopping the application server, we will create a systemd service and socket files.

First, create a Gunicorn socket file.

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

Add the following lines:

[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
[Install]
WantedBy=sockets.target

Save and close the file.

Next, create a systemd service file for Gunicorn.

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

Add following lines

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

[Service]
User=[username]
Group=www-data
WorkingDirectory=/var/www/django_project
ExecStart=/var/www/django_project/env/bin/gunicorn \
          --access-logfile - \
          --workers 3 \
          --bind unix:/run/gunicorn.sock \
          django_project.wsgi:application
[Install]
WantedBy=multi-user.target

Note: Replace [username] with your username.

Next, reload the systemd daemon with the following command:

sudo systemctl daemon-reload

Next, start the Gunicorn service and enable it to start at system reboot:

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

9. Configure Nginx

Now, we will configure Nginx as a reverse proxy to Gunicorn project server.

Create an nginx configuration file using following command:

sudo nano /etc/nginx/sites-available/django.conf

Add following lines:

server {  
	listen 80;
	server_name django.example.com;    
	location = /favicon.ico { access_log off; log_not_found off; }
	location /static/ {
		root /var/www/django_project;
	}
	location / {
		include proxy_params;
		proxy_pass http://unix:/run/gunicorn.sock;
	}
}

Note: Replace django.example.com with your domain name or server IP.

Save and close it.

Create symbolic link in sites-enabled to activate the conf file.

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

Verify the Nginx for any configuration error.

sudo nginx -t

Output:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Finally, restart the Nginx service.

sudo systemctl restart nginx

That’s it, the installation and configuration has been done successfully.

In this article, we have seen how to set up Django with Postgres, Nginx, and Gunicorn on Ubuntu 22.04.

Related Articles