In this guide, we’ll walk you through setting up Django with PostgreSQL, Nginx, and Gunicorn on an Ubuntu 22.04 server. Django, a robust Python-based web framework, follows the Model-Template-View (MTV) architecture, and while it includes a development server for local testing, a more powerful setup is required for production environments.
This tutorial covers creating a Python virtual environment, installing Django, setting up PostgreSQL, configuring Gunicorn as the application server, and using Nginx as a reverse proxy for enhanced security and performance.
Prerequisites:
- A server running Ubuntu 22.04
- Root or administrative privileges
- A domain name pointing to your server’s IP address
Step 1: Update Your Server
Start by ensuring your server is up to date:
sudo apt update && sudo apt upgrade -y
Step 2: Install Necessary Packages
Install the essential packages for Python, PostgreSQL, and Nginx:
sudo apt install python3-pip python3-dev python3-venv libpq-dev postgresql postgresql-contrib nginx -y
Step 3: Configure PostgreSQL Database
Create a PostgreSQL database and user for Django.
Access PostgreSQL:
sudo -u postgres psql
Create a new database:
CREATE DATABASE databasename;
Create a user for the database:
CREATE USER databaseuser WITH PASSWORD 'password';
Set connection parameters:
ALTER ROLE databaseuser SET client_encoding TO 'utf8';
ALTER ROLE databaseuser SET default_transaction_isolation TO 'read committed';
ALTER ROLE databaseuser SET timezone TO 'UTC';
Grant the user privileges:
GRANT ALL PRIVILEGES ON DATABASE databasename TO databaseuser;
Exit the PostgreSQL prompt:
\q
Step 4: Create a Python Virtual Environment
First, upgrade pip
:
sudo pip3 install --upgrade pip
Create a directory for your project:
sudo mkdir /var/www/django_project && cd /var/www/django_project
Change the directory owner to your user:
sudo chown -R user:user ../django_project
Create and activate the virtual environment:
python3 -m venv env
source env/bin/activate
Install Django, Gunicorn, and PostgreSQL dependencies:
pip install django gunicorn psycopg2-binary
Step 5: Create and Configure Django Project
Create a new Django project:
django-admin startproject django_project /var/www/django_project
Edit the settings.py
file to add your domain and database configuration:
nano django_project/settings.py
Add your domain to ALLOWED_HOSTS
:
ALLOWED_HOSTS = ['django.example.com', 'localhost', 'server_ip']
Configure the PostgreSQL database:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'databasename',
'USER': 'databaseuser',
'PASSWORD': 'password',
'HOST': 'localhost',
}
}
Add static file settings:
import os
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
Run database migrations and collect static files:
python manage.py migrate
python manage.py collectstatic
Step 6: Test Django Development Server
Allow Django’s default development port through the firewall:
sudo ufw allow 8000/tcp
Start the Django server:
python manage.py runserver 0.0.0.0:8000
Visit http://server_ip_or_domain_name.com:8000
in your browser to check if the setup works, then stop the server.
Step 7: Test Gunicorn
Run Gunicorn to verify it can serve your Django application:
gunicorn --bind 0.0.0.0:8000 django_project.wsgi
Visit your server IP with port 8000 in the browser, and if all is fine, stop Gunicorn and deactivate the virtual environment:
deactivate
Step 8: Create Systemd Service and Socket for Gunicorn
Create a systemd socket file for Gunicorn:
sudo nano /etc/systemd/system/gunicorn.socket
Add:
[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
[Install]
WantedBy=sockets.target
Next, create the systemd service file:
sudo nano /etc/systemd/system/gunicorn.service
Add:
[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
Replace [username]
with your user.
Reload systemd and enable Gunicorn:
sudo systemctl daemon-reload
sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket
sudo systemctl start gunicorn
sudo systemctl enable gunicorn
Step 9: Configure Nginx as Reverse Proxy
Create an Nginx configuration file:
sudo nano /etc/nginx/sites-available/django.conf
Add:
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;
}
}
Create a symbolic link to enable the configuration:
sudo ln -s /etc/nginx/sites-available/django.conf /etc/nginx/sites-enabled/
Test Nginx configuration:
sudo nginx
-t
Restart Nginx:
sudo systemctl restart nginx
Conclusion
Congratulations! You’ve successfully set up Django with PostgreSQL, Nginx, and Gunicorn on your Ubuntu 22.04 server.