Monday, December 1, 2025

thumbnail

Using Nginx and Gunicorn for Python Web Application Deployment

 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

Get Directions

Subscribe by Email

Follow Updates Articles from This Blog via Email

No Comments

About

Search This Blog

Powered by Blogger.

Blog Archive