Django with Nginx and Gunicorn on Ubuntu 24.04

By Raman Kumar

Updated on Mar 10, 2026

Django with Nginx and Gunicorn on Ubuntu 24.04

Learn how to deploy Django on Ubuntu 24.04 using Gunicorn as the WSGI application server and Nginx as the reverse proxy. This setup is widely used in production environments because it is stable, efficient, and easy to maintain.

Introduction

Deploying a Django application to production requires a reliable web server, a stable application server, and a clean configuration that ensures performance and security.

Our goal is to create a deployment structure that is secure, scalable, and suitable for real-world applications.

Step 1 - Update the Server

We begin by ensuring the system packages are fully updated.

sudo apt update && sudo apt upgrade -y

Install essential development packages required for building Python dependencies.

sudo apt install python3 python3-venv python3-pip python3-dev build-essential -y

These packages allow Python modules with compiled extensions to install correctly.

Step 2 - Create a Project Directory

Production deployments should never run directly from a home directory.
We create a clean application directory.

sudo mkdir -p /var/www/django_app

Give ownership to the current user.

sudo chown -R $USER:$USER /var/www/django_app

Move inside the directory.

cd /var/www/django_app

Step 3 - Create Python Virtual Environment

A virtual environment isolates project dependencies and prevents conflicts with system packages.

Create the environment:

python3 -m venv venv

Activate it:

source venv/bin/activate

Upgrade pip:

pip install --upgrade pip

Step 4 - Install Django and Gunicorn

Install the core dependencies.

pip install django gunicorn

If the project uses additional dependencies, install them from the requirements file.

pip install -r requirements.txt

Step 5 - Create or Upload the Django Project

If starting fresh, create the project.

django-admin startproject project .

Run database migrations.

python manage.py migrate

Create an admin user.

python manage.py createsuperuser

This ensures static assets are served efficiently by Nginx rather than Django.

Step 6 - Configure Django for Production

Open the Django settings file.

nano project/settings.py

Update the ALLOWED_HOSTS setting.

ALLOWED_HOSTS = ["server_ip", "domain.com"]

Add static file configuration.

STATIC_ROOT = "/var/www/django_app/static"

Save and exit.

Collect static files.

python manage.py collectstatic

Step 7 - Install and Configure Nginx

Install Nginx.

sudo apt install nginx -y

Allow HTTP through the firewall.

sudo ufw allow 'Nginx Full'

Create a new site configuration.

sudo nano /etc/nginx/sites-available/django_app

Add the following configuration.

server {
    listen 80;
    server_name domain.com server_ip;

    location = /favicon.ico { access_log off; log_not_found off; }

    location /static/ {
        root /var/www/django_app;
    }

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

Enable the site.

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

Test configuration.

sudo nginx -t

Reload Nginx.

sudo systemctl restart nginx

Step 8 - Create Gunicorn Systemd Service

Gunicorn creates the socket file used by Nginx. Ensure proper permissions exist.

Create runtime directory.

sudo mkdir -p /run/gunicorn

Set permissions.

sudo chown www-data:www-data /run/gunicorn

Running Gunicorn manually is not suitable for production. We configure systemd so the application runs automatically.

Create the service file.

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

Add the configuration below.

[Unit]
Description=Gunicorn daemon for Django
After=network.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/django_app
ExecStart=/var/www/django_app/venv/bin/gunicorn \
          --workers 3 \
          --bind unix:/run/gunicorn/gunicorn.sock \
          project.wsgi:application

[Install]
WantedBy=multi-user.target

Save the file.

Reload systemd.

sudo systemctl daemon-reload

Start Gunicorn.

sudo systemctl start gunicorn

Enable it on boot.

sudo systemctl enable gunicorn

Verify status.

sudo systemctl status gunicorn

Step 9 - Configure Static File Serving

Nginx should handle static assets to improve performance.

Ensure static files exist.

python manage.py collectstatic

Nginx already serves /static/ from:

/var/www/django_app/static

This avoids unnecessary load on Gunicorn.

Step 10 - Secure the Application with HTTPS

Production deployments should always use SSL.

Install Certbot.

sudo apt install certbot python3-certbot-nginx -y

Generate the certificate.

sudo certbot --nginx -d domain.com

Certbot automatically updates the Nginx configuration and sets up automatic renewal.

Troubleshooting

If you get error in gunicorn service, try to run gunicorn manually in debug mode:

gunicorn project.wsgi:application --bind 0.0.0.0:8000 --workers 2 --log-level debug

Step 12 - Production Optimization

A stable deployment requires a few practical optimizations.

Increase Gunicorn workers

workers = (2 × CPU cores) + 1

Example:

--workers 5

Enable logging

Logs help diagnose production issues.

Gunicorn logs can be viewed with:

journalctl -u gunicorn

Nginx logs are located at:

  • /var/log/nginx/access.log
  • /var/log/nginx/error.log

Restart services after updates

sudo systemctl restart gunicorn
sudo systemctl reload nginx

Final Thoughts

Deploying Django with Gunicorn and Nginx on Ubuntu 24.04 creates a production-ready environment capable of serving real applications reliably.

Gunicorn manages Python application execution, while Nginx efficiently handles HTTP requests, static files, and reverse proxy responsibilities. This architecture ensures stability, performance, and scalability.

By following this deployment approach, we build a clean and maintainable infrastructure that can support both small projects and large production workloads.