Deploying a Django project to production is one of the most important steps for every developer. While Django’s built-in development server is useful for local testing, it is not suitable for production environments.
For production deployment, developers commonly use Gunicorn as the WSGI server and Nginx as the reverse proxy server. This setup improves performance, security, and scalability.
In this guide, you will learn Django deployment using Gunicorn and Nginx step by step on an Ubuntu server.
Why Use Gunicorn and Nginx for Django Deployment?
Before deployment, it is important to understand why this combination is widely recommended.
Gunicorn
Gunicorn (Green Unicorn) is a Python WSGI HTTP Server for UNIX.
It helps by:
- Running Django applications efficiently
- Managing multiple worker processes
- Handling production traffic better than Django’s built-in server
Nginx
Nginx acts as a reverse proxy.
It helps by:
- Serving static and media files faster
- Handling client requests
- Forwarding requests to Gunicorn
- Improving security and performance
Server Requirements
Before starting, ensure you have:
- Ubuntu Server (20.04 / 22.04 recommended)
- Python installed
- Virtual environment ready
- Django project completed
- Domain or server IP
- SSH access to server
Step 1: Update Ubuntu Server
First, update your server packages.
sudo apt update
sudo apt upgrade -y
This ensures your system is ready for deployment.
Step 2: Install Python Virtual Environment
Install required packages:
sudo apt install python3-pip python3-dev python3-venv nginx -y
Now create your project directory:
mkdir myproject
cd myproject
Create virtual environment:
python3 -m venv venv
source venv/bin/activate
Step 3: Install Django and Gunicorn
Inside the virtual environment:
pip install django gunicorn
Also install your project dependencies:
pip install -r requirements.txt
Step 4: Configure Django for Production
Open settings.py:
nano settings.py
Update these important settings:
Allowed Hosts
ALLOWED_HOSTS = ['your-server-ip', 'yourdomain.com']
Static Files
STATIC_ROOT = BASE_DIR / 'static/'
Debug Mode
DEBUG = False
Never keep DEBUG=True in production.
Step 5: Run Migrations and Collect Static Files
Apply migrations:
python manage.py migrate
Create static files:
python manage.py collectstatic
Create superuser if needed:
python manage.py createsuperuser
Step 6: Test Gunicorn
Run Gunicorn manually:
gunicorn --bind 0.0.0.0:8000 projectname.wsgi:application
Replace projectname with your Django project name.
Visit:
http://your-server-ip:8000
If the project loads, Gunicorn is working correctly.
Step 7: Create Gunicorn Systemd Service
Create service file:
sudo nano /etc/systemd/system/gunicorn.service
Paste this:
[Unit]
Description=Gunicorn daemon
After=network.target[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/myproject
ExecStart=/home/ubuntu/myproject/venv/bin/gunicorn \
--workers 3 \
--bind unix:/home/ubuntu/myproject/myproject.sock \
projectname.wsgi:application[Install]
WantedBy=multi-user.target
Save and exit.
Now start service:
sudo systemctl start gunicorn
sudo systemctl enable gunicorn
Check status:
sudo systemctl status gunicorn
Step 8: Configure Nginx
Create Nginx config:
sudo nano /etc/nginx/sites-available/myproject
Paste this:
server {
listen 80;
server_name yourdomain.com your-server-ip; location = /favicon.ico { access_log off; log_not_found off; } location /static/ {
root /home/ubuntu/myproject;
} location /media/ {
root /home/ubuntu/myproject;
} location / {
include proxy_params;
proxy_pass http://unix:/home/ubuntu/myproject/myproject.sock;
}
}
Save and exit.
Enable config:
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
Test Nginx:
sudo nginx -t
Restart Nginx:
sudo systemctl restart nginx
Step 9: Allow Firewall Access
If using UFW firewall:
sudo ufw allow 'Nginx Full'
Then:
sudo ufw enable
Now your Django project should be live.
Step 10: Secure with SSL (Recommended)
For HTTPS security, install Certbot:
sudo apt install certbot python3-certbot-nginx -y
Run:
sudo certbot --nginx
This will automatically configure SSL for your domain.
Common Deployment Errors
502 Bad Gateway
Usually caused by:
- Gunicorn not running
- Wrong socket path
- Permission issues
Static Files Not Loading
Usually caused by:
- Missing
collectstatic - Wrong STATIC_ROOT
- Incorrect Nginx path
DisallowedHost Error
Fix by updating:
ALLOWED_HOSTS
inside settings.py.
Final Thoughts
Django deployment using Gunicorn and Nginx is the most reliable production setup for professional projects.
This combination provides:
- Better performance
- Improved security
- Production readiness
- Easy scalability
Whether you are deploying on VPS, DigitalOcean, AWS EC2, or any Ubuntu server, this setup is highly recommended.
If you want stable and professional Django hosting, Gunicorn + Nginx is the best choice.
Start with this deployment method and build production-ready Django applications with confidence.