Aimed at developers shipping small applications to a single internet-facing host rather than to a managed PaaS. Currently focused on Flask behind Caddy; will expand with other stacks as they earn their own walk-throughs. Read this after host-hardening and edge-hardening — the deployment recipes assume the box and the edge are already configured to a defensible baseline.
Deploying a Flask Tools Site on a Hardened VPS Behind Caddy
Tested on: Ubuntu 24.04 LTS, Python 3.12.3, Caddy 2.x, gunicorn 23.0, Flask 3.x, SQLite as the data store. The pattern is portable to any small Python web app — drop in whichever Flask / Starlette / FastAPI codebase you have. Why this matters Most Flask deployment tutorials end at flask run --host 0.0.0.0 and a hand-wave about Nginx. That gap — between “the app starts” and “the app is a service my colleagues would trust at 2am” — is where the operationally interesting decisions live: which user runs it, how it talks to the reverse proxy, where its secrets live, how it survives a reboot, how its certificate renews itself. ...