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.