Deployment
The development server started by flask run is single-process and unhardened — it is for development only. Production requires a proper WSGI server behind a reverse proxy.
Architecture Overview
Choosing Components
- Gunicorn (first choice on Linux): mature and stable;
-wmulti-process plus optionalgevent/gthreadconcurrency models - uWSGI: feature-rich, more complex configuration
- Waitress: pure Python, cross-platform — the main option on Windows
- Reverse proxy: Nginx / Caddy (automatic HTTPS)
Gunicorn
A good starting worker count is CPU cores × 2 + 1. Bind to 127.0.0.1 rather than 0.0.0.0 so only the local Nginx can reach it.
Nginx Reverse Proxy
Behind a proxy, Flask must trust the forwarded headers — otherwise url_for(..., _external=True) generates http links:
systemd Service
Containerization
Copying requirements.txt first and installing dependencies separately makes good use of Docker layer caching.
Production Checklist
-
DEBUG=False;SECRET_KEYcomes from an environment variable and is sufficiently random - Database URLs and third-party secrets all injected via environment variables
-
ProxyFixconfigured and forwarding headers set in Nginx - Static files served by Nginx/CDN
- Logs to stdout (containers) or rotating files (see the Logging chapter)
- A health-check endpoint (e.g.
GET /healthzreturning 200) - HTTPS enforced (HSTS); session cookies set
Secure