Deploying Django with uWSGI and Nginx: A Step-by-Step Guide

🚀 Deploying Django with uWSGI and Nginx: A Step-by-Step Guide
If you’ve built your Django app and it’s ready for the world, the next big question is: How do I deploy it efficiently in production?
A common, reliable stack is:
- Django (your app)
- uWSGI (application server)
- Nginx (reverse proxy and static/media handler)
This combination is fast, secure, and scalable.
1. Why uWSGI + Nginx?
uWSGI is a high-performance WSGI server that talks directly to Django.
Nginx is a lightweight web server that handles incoming requests, serves static files, and forwards dynamic requests to uWSGI.
Advantages:
- Handles more traffic with less CPU/RAM
- Better static/media file delivery
- Security through process isolation
- Easier scaling
2. Production Checklist Before Deployment
- ✅ Python virtual environment ready
- ✅ Django settings configured for production (
DEBUG=False
,ALLOWED_HOSTS
) - ✅ Static files collected (
python manage.py collectstatic
) - ✅ Database migrations done (
python manage.py migrate
)
3. Installing Dependencies
sudo apt update && sudo apt upgrade -y
sudo apt install python3-pip python3-venv nginx uwsgi uwsgi-plugin-python3 -y
python3 -m venv venv
source venv/bin/activate
pip install django uwsgi
4. uWSGI Configuration
Create a file myproject_uwsgi.ini
:
[uwsgi]
chdir = /path/to/myproject
module = myproject.wsgi:application
home = /path/to/myproject/venv
master = true
processes = 5
socket = /run/uwsgi/myproject.sock
chmod-socket = 660
vacuum = true
die-on-term = true
Explanation:
chdir
: Project rootmodule
: Django WSGI entry pointhome
: Virtualenv pathsocket
: UNIX socket for fast communication with Nginxprocesses
: Number of worker processeschmod-socket
: Set permissions so Nginx can connect
5. uWSGI Service with systemd
Create /etc/systemd/system/myproject.service
:
[Unit]
Description=uWSGI instance to serve myproject
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/path/to/myproject
Environment="PATH=/path/to/myproject/venv/bin"
ExecStart=/path/to/myproject/venv/bin/uwsgi --ini myproject_uwsgi.ini
[Install]
WantedBy=multi-user.target
sudo systemctl start myproject
sudo systemctl enable myproject
6. Nginx Configuration
Create /etc/nginx/sites-available/myproject
:
server {
listen 80;
server_name example.com;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /path/to/myproject;
}
location /media/ {
root /path/to/myproject;
}
location / {
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/myproject.sock;
}
}
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
sudo nginx -t
sudo systemctl restart nginx
7. Security & Performance Tips
- Use UNIX sockets instead of TCP for faster local communication.
- Enable Gzip in Nginx for smaller response sizes.
- Set
keepalive_timeout
in Nginx to reduce idle connections. - Run uWSGI in master mode with multiple workers for better concurrency.
- Use
--lazy-apps
in uWSGI if you have large initialization times.
8. Final Test
sudo systemctl status myproject
sudo systemctl status nginx
Visit http://example.com
in your browser — your Django app should be live 🎉.
Conclusion
Using uWSGI and Nginx for Django deployment gives you speed, stability, and scalability. This setup is battle-tested in production environments and is highly configurable for future growth.