Getting a Python Service Running Reliably
Last updated:
Never run the development server in production
The built-in development servers in Python frameworks are single-threaded, unoptimised and explicitly not intended for production. They are also frequently found running production systems.
Behind a production application server, with a reverse proxy in front and a process supervisor keeping it alive. That is the minimum viable arrangement.
The deployment stack
- A production application server running the Python code
- A reverse proxy handling TLS, static files and buffering
- A process supervisor restarting anything that exits
- Separate worker processes for background tasks
- Log output collected rather than written to a file nobody reads
Configuration from the environment
- No credentials in the repository, ever
- Different configuration per environment without code changes
- Configuration validated at startup, failing fast if something is missing
- Secrets managed properly rather than in a plain file
An application that starts successfully with a missing configuration value and fails at three in the morning is a preventable problem.
Deploy from version control
| Requirement | Why |
|---|---|
| Deploy a specific commit | You know what is running |
| Dependencies installed at deploy | Reproducible |
| Migrations run in order | Schema matches code |
| Atomic switch | No half-deployed state |
| Tested rollback | Recovery is routine |
Health checks and graceful shutdown
A health endpoint lets monitoring and load balancers know whether the service is actually working, not just running. It should check dependencies rather than always returning success.
Graceful shutdown — finishing in-flight requests before exiting — means deployments do not drop work. Both are small pieces of work with disproportionate operational value.
Frequently asked questions
Containers or plain deployment?
How do we handle secrets?
What about zero-downtime deployment?
Should workers deploy with the application?
Running the development server in production?
It happens more than you would expect. Worth checking, and quick to fix properly.
Related services
What we build for problems like this one