Hands-on guide series
Python Web Apps in Production: A Hands-On Guide
A six-part, hands-on guide to running a Python web app in production on a single VPS: a virtualenv and Flask under gunicorn, a systemd service, nginx over a unix socket, environment secrets, worker sizing, and zero-downtime reloads with health checks. Every command tested on a live Ubuntu 24.04 server.
What you will build
Security is layers, not a switch. Each part closes a different category of attack, from the automated sweep that finds a brand-new server, to the day one gets in anyway. Read them in order, or jump to what you need.
- 1
Set Up a venv and Run a Python Web AppSee the destination first, then install Python and gunicorn on a bare slice and run a real Python web app that answers a 200 on Ubuntu 24.04.8 min - 2
Run gunicorn Under systemdTurn a Flask app into a gunicorn systemd service that starts on boot and restarts on failure, then kill it and watch systemd bring it back with a new PID.6 min - 3
Put gunicorn Behind nginxPut gunicorn behind nginx over a unix socket, forward the right proxy headers, and prove a request through nginx returns 200 from the Flask app.6 min - 4
Flask Config, Environment and SecretsConfigure a Python app through the environment and keep its secrets in a 600 file the service user reads, with the value masked in every log line.6 min - 5
Workers and ConcurrencySize gunicorn workers with the two times cores plus one rule, see the worker PIDs, and watch concurrent requests spread across every worker.6 min - 6
Zero-Downtime Reload and Health ChecksUse gunicorn graceful reload with SIGHUP so a request loop stays 200, add a health check endpoint, and send structured JSON logs to journald.6 min