1. What Each Component Does
Gunicorn
A WSGI application server that runs your Python code.
Handles multiple workers, timeouts, process management.
Not optimal at serving static files or handling slow clients.
Nginx
A high-performance reverse proxy.
Sits in front of Gunicorn.
Handles:
TLS/SSL termination
Serving static files efficiently
Managing slow clients
Rate limiting and security filters
Combined Setup
Client → Nginx → Gunicorn → Python App
This setup is fast, secure, and scalable.
2. Folder Structure (Example)
/var/www/myapp/
│
├── myapp/ # Python package
│ ├── __init__.py
│ └── app.py # Flask app or similar
│
├── venv/ # Virtual environment
├── gunicorn.service # systemd service file
└── nginx.conf # Nginx site configuration
3. Installing Dependencies
Install Nginx
On Ubuntu/Debian:
sudo apt update
sudo apt install nginx
Install Gunicorn and your app
python3 -m venv venv
source venv/bin/activate
pip install gunicorn flask # or Django, FastAPI, etc.
4. Running Gunicorn (Basic Test)
For a Flask app with app = Flask(__name__):
gunicorn --bind 0.0.0.0:8000 myapp.app:app
For Django:
gunicorn --bind 0.0.0.0:8000 myproject.wsgi
You should now see the app at:
http://server-ip:8000
5. Creating a systemd Service for Gunicorn
Create /etc/systemd/system/gunicorn.service:
[Unit]
Description=Gunicorn service for Python app
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/myapp
ExecStart=/var/www/myapp/venv/bin/gunicorn \
--workers 3 \
--bind unix:/var/www/myapp/gunicorn.sock \
myapp.app:app
Restart=always
[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable gunicorn
sudo systemctl start gunicorn
sudo systemctl status gunicorn
This runs Gunicorn as a background service using a Unix domain socket instead of a TCP port.
6. Configuring Nginx as Reverse Proxy
Create /etc/nginx/sites-available/myapp:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://unix:/var/www/myapp/gunicorn.sock:;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Optional: serve static files
location /static/ {
alias /var/www/myapp/static/;
}
}
Enable it:
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
Now your app is live at http://example.com.
7. Adding HTTPS with Let’s Encrypt (Recommended)
Use Certbot:
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com
This generates SSL certificates and updates your Nginx config automatically.
8. Scaling Gunicorn
Gunicorn workers handle concurrent requests. A common rule of thumb:
workers = 2 × CPU cores + 1
Example:
gunicorn --workers 5 --bind unix:gunicorn.sock ...
For async workloads, consider:
gevent worker type
uvicorn + uvicorn.workers.UvicornWorker for ASGI apps (FastAPI, Starlette)
9. Serving Static and Media Files Efficiently
Let Nginx handle static assets:
location /static/ {
alias /var/www/myapp/static/;
}
For Django:
python manage.py collectstatic
10. Common Production Best Practices
✔ Run Nginx and Gunicorn with non-root accounts
✔ Use systemd for automatic restart
✔ Enable firewall rules (UFW)
✔ Monitor logs:
Gunicorn logs: journalctl -u gunicorn
Nginx logs: /var/log/nginx/access.log and error.log
✔ Use health checks
✔ Store secrets in environment variables
✔ Automate deployments (Ansible, GitHub Actions, Docker)
11. Typical Deployment Flow (At a Glance)
Install Nginx + Python venv
Install and test Gunicorn
Configure systemd Gunicorn service
Configure Nginx reverse proxy
Enable HTTPS
Reload services
Monitor and optimize
Summary (In One Sentence)
Use Nginx as a secure, efficient reverse proxy and static file server, while Gunicorn runs your Python application as the WSGI server behind it—together they form a reliable, production-ready deployment stack.
Learn Fullstack Python Training in Hyderabad
Read More
How to Deploy a Django Application on AWS
Setting Up Continuous Deployment (CD) for Full Stack Python Projects
Using Docker to Containerize Your Full Stack Python Application
Continuous Integration (CI) in Full Stack Python Development
At Our Quality Thought Training Institute in Hyderabad
Subscribe by Email
Follow Updates Articles from This Blog via Email
No Comments