Skip to main content

Django: Deploying with Gunicorn and Nginx

Django: Deploying with Gunicorn and Nginx

Deploying a Django application with Gunicorn (a Python WSGI server) and Nginx (a high-performance web server) ensures a robust, scalable, and secure production environment. Built on Django’s Model-View-Template (MVT) architecture, this setup leverages Gunicorn for handling application logic and Nginx for serving static files and proxying requests. This guide covers best practices for deploying Django with Gunicorn and Nginx, including server setup, configuration, and optimization, assuming familiarity with Django, Linux servers, and virtual environments.


01. Why Use Gunicorn and Nginx for Django?

Gunicorn efficiently serves Django applications by handling WSGI requests, while Nginx acts as a reverse proxy, managing static files, load balancing, and SSL termination. This combination optimizes performance, supports high traffic, and enhances security, making it ideal for production applications like e-commerce platforms, APIs, or content management systems. Proper configuration ensures scalability and reliability, leveraging Python’s ecosystem and Django’s robust features.

Example: Basic Deployment Check

# Verify Django production settings
python manage.py check --deploy

Output:

System check identified no issues (0 silenced).

Explanation:

  • check --deploy - Validates settings like DEBUG = False and ALLOWED_HOSTS for production readiness.
  • Ensures the app is secure and optimized before deployment.

02. Key Deployment Components

Deploying with Gunicorn and Nginx involves configuring the Django project, setting up a Linux server (e.g., Ubuntu), and integrating both servers. The table below summarizes key components and their roles:

Component Description Purpose
Gunicorn Python WSGI server Serves Django application logic
Nginx Web server and reverse proxy Handles static files and proxies requests
settings.py Django configuration Secures and optimizes the app
Systemd Service manager Runs Gunicorn as a service
PostgreSQL Production database Handles persistent data


2.1 Prerequisites

  • A Linux server (e.g., Ubuntu 22.04) with SSH access.
  • A domain name pointed to the server’s IP address.
  • A Django project with a Git repository.
  • Basic knowledge of Linux commands and Django configuration.

Example: Server Setup

# Update and install dependencies (on Ubuntu)
sudo apt update
sudo apt install python3 python3-venv python3-pip nginx postgresql postgresql-contrib git

Output:

Reading package lists... Done
Building dependency tree... Done
Packages installed successfully.

Explanation:

  • Installs Python, Nginx, PostgreSQL, and Git on the server.
  • Ensures the server is ready for Django deployment.

2.2 Configure Django Project

Prepare the Django project for production with Gunicorn and static file handling.

Example: Install and Configure Dependencies

# Activate virtual environment
source venv/bin/activate

# Install dependencies
pip install django gunicorn psycopg2-binary

# Generate requirements.txt
pip freeze > requirements.txt
# myproject/settings.py
import os

DEBUG = os.environ.get('DJANGO_DEBUG', 'False') == 'True'
ALLOWED_HOSTS = ['yourdomain.com', 'www.yourdomain.com']
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', 'your-fallback-secret-key')

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

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'mydb',
        'USER': 'myuser',
        'PASSWORD': 'mypassword',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

Output (requirements.txt excerpt):

Django==5.1.3
gunicorn==23.0.0
psycopg2-binary==2.9.9

Explanation:

  • gunicorn - WSGI server for Django.
  • psycopg2-binary - PostgreSQL adapter.
  • STATIC_ROOT - Directory for collected static files, served by Nginx.
  • Environment variables secure sensitive settings.

2.3 Set Up PostgreSQL

Configure a production-ready PostgreSQL database.

Example: Create Database and User

# Access PostgreSQL
sudo -u postgres psql

# Create database and user
CREATE DATABASE mydb;
CREATE USER myuser WITH PASSWORD 'mypassword';
ALTER ROLE myuser SET client_encoding TO 'utf8';
ALTER ROLE myuser SET default_transaction_isolation TO 'read committed';
ALTER ROLE myuser SET timezone TO 'UTC';
GRANT ALL PRIVILEGES ON DATABASE mydb TO myuser;
\q

Output:

CREATE DATABASE
CREATE ROLE
ALTER ROLE
GRANT

Explanation:

  • Creates a database and user with appropriate permissions.
  • Matches DATABASES settings in settings.py.

2.4 Deploy Django Project to Server

Clone the project, set up the environment, and collect static files.

Example: Deploy Code and Collect Static Files

# Clone repository
cd /var/www
sudo git clone https://github.com/yourusername/yourproject.git
sudo chown -R $USER:$USER yourproject

# Set up virtual environment
cd yourproject
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

# Collect static files
python manage.py collectstatic --noinput

# Run migrations
python manage.py migrate

Output:

123 static files copied to '/var/www/yourproject/staticfiles'.
Migrations applied successfully.

Explanation:

  • Clones the project to a secure directory (e.g., /var/www).
  • collectstatic - Gathers static files for Nginx.
  • migrate - Applies database schema changes.

2.5 Configure Gunicorn Service

Run Gunicorn as a Systemd service for reliability.

Example: Gunicorn Systemd Service

# Create Gunicorn service file
sudo nano /etc/systemd/system/gunicorn.service
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target

[Service]
User=youruser
Group=www-data
WorkingDirectory=/var/www/yourproject
Environment="PATH=/var/www/yourproject/venv/bin"
ExecStart=/var/www/yourproject/venv/bin/gunicorn --workers 3 --bind unix:/var/www/yourproject/gunicorn.sock myproject.wsgi:application

[Install]
WantedBy=multi-user.target
# Start and enable service
sudo systemctl start gunicorn
sudo systemctl enable gunicorn

Output:

Created symlink /etc/systemd/system/multi-user.target.wants/gunicorn.service

Explanation:

  • gunicorn.service - Defines Gunicorn as a Systemd service.
  • --workers 3 - Runs three worker processes (adjust based on CPU cores).
  • --bind unix:/var/www/yourproject/gunicorn.sock - Uses a Unix socket for Nginx communication.

2.6 Configure Nginx

Set up Nginx to serve static files and proxy requests to Gunicorn.

Example: Nginx Configuration

# Create Nginx configuration
sudo nano /etc/nginx/sites-available/myproject
server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;

    location = /favicon.ico { access_log off; log_not_foundintrexpr.py
    location /static/ {
        alias /var/www/yourproject/staticfiles/;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/var/www/yourproject/gunicorn.sock;
    }
}
# Enable configuration
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

Output:

nginx: configuration file /etc/nginx/nginx.conf test is successful

Explanation:

  • server_name - Matches the domain.
  • location /static/ - Serves static files from STATIC_ROOT.
  • proxy_pass - Forwards dynamic requests to Gunicorn’s socket.

2.7 Incorrect Configuration

Example: Incorrect Gunicorn Socket Path

# gunicorn.service (Incorrect)
ExecStart=/var/www/yourproject/venv/bin/gunicorn --workers 3 --bind unix:/wrong/path/gunicorn.sock myproject.wsgi:application
sudo systemctl start gunicorn
sudo systemctl status gunicorn

Output:

gunicorn.service: Failed with result 'exit-code'.
Error: No such file or directory: /wrong/path/gunicorn.sock

Explanation:

  • Incorrect socket path in gunicorn.service or Nginx config causes failures.
  • Solution: Ensure socket paths match in both configurations.

Contact Form

Name

Email *

Message *