This guide shows the standard way to run a production Python web app on a Linux VPS: Gunicorn as the WSGI server, Nginx as the reverse proxy, and systemd to keep it running. It works for Flask, FastAPI (with a WSGI/ASGI worker) and Django.

1. Set up a virtual environment

sudo apt install python3-venv nginx -y
cd /var/www/myapp
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt gunicorn

2. Test Gunicorn

gunicorn --bind 127.0.0.1:8000 myapp:app   # Flask: module:app
# or for Django: gunicorn myproject.wsgi:application --bind 127.0.0.1:8000

3. Run it under systemd

Create /etc/systemd/system/myapp.service:

[Unit]
Description=myapp
After=network.target

[Service]
User=www-data
WorkingDirectory=/var/www/myapp
ExecStart=/var/www/myapp/venv/bin/gunicorn --workers 3 --bind 127.0.0.1:8000 myapp:app
Restart=always

[Install]
WantedBy=multi-user.target
sudo systemctl enable --now myapp

4. Put Nginx in front

server {
    listen 80;
    server_name example.com;
    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
sudo nginx -t && sudo systemctl reload nginx

5. Add HTTPS

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d example.com

Your app now runs reliably behind Nginx with TLS. Scale by increasing Gunicorn workers (a common starting point is 2 × CPU cores + 1) or upgrading your VPS plan.