Deployment Basics
10 examples to get you started with Containers & Deploy - 7 basic and 3 intermediate.
Search across all documentation pages
10 examples to get you started with Containers & Deploy - 7 basic and 3 intermediate.
uv venv && source .venv/bin/activate
uv pip install "fastapi>=0.115" "uvicorn[standard]>=0.34" "gunicorn>=23.0" "flask>=3.1"Flask exposes a WSGI callable consumed by Gunicorn.
from flask import Flask
app = Flask(__name__)
@app.get("/health")
def health():
return {"status": "ok"}gunicorn -w 2 -b 0.0.0.0:8000 'app:app'app:app means module app, variable app-w workers handle concurrent requests (sync)Related: Gunicorn & Uvicorn - worker tuning
FastAPI apps are ASGI - run with Uvicorn or Gunicorn+Uvicorn worker.
from fastapi import FastAPI
app = FastAPI()
@app.get("/health")
async def health():
return {"status": "ok"}uvicorn app:app --host 0.0.0.0 --port 80000.0.0.0 in containers, not 127.0.0.1Related: Gunicorn & Uvicorn - production ASGI
Read port from environment for 12-factor deploys.
import os
PORT = int(os.environ.get("PORT", "8000"))PORTuvicorn without envint() and fail fast on invalid valuesRelated: Configuration & Secrets in Prod - env config
Understand who accepts TCP connections.
Client -> Load Balancer -> Gunicorn master -> worker processes -> your app
Related: Dockerizing Python - container entrypoint
Never use Flask/FastAPI built-in dev servers in production.
# dev only
flask --app app run --debug
# prod
gunicorn -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000 app:app--reload is for local iteration onlyRelated: Deployment Best Practices - prod checklist
Drain in-flight requests on SIGTERM from orchestrators.
import signal
def handle_sigterm(signum, frame):
print("shutting down gracefully")
signal.signal(signal.SIGTERM, handle_sigterm)--graceful-timeoutRelated: Zero-Downtime Deploys - rolling updates
Serve static assets from CDN or reverse proxy, not Python workers.
location /static/ { alias /var/www/static/; }
location / { proxy_pass http://app:8000; }Related: Kubernetes for Python Apps - ingress
Manage connections with ASGI lifespan context.
from contextlib import asynccontextmanager
from fastapi import FastAPI
@asynccontextmanager
async def lifespan(app: FastAPI):
# startup
yield
# shutdown cleanup
app = FastAPI(lifespan=lifespan)@app.on_event with lifespanRelated: Health & Readiness - probe design
Each worker loads a full copy of your app and models.
gunicorn -w 4 app:app
# 4x import cost, 4x ML model RAM if loaded at importRelated: Performance Monitoring (APM) - prod tuning
Document the exact prod command in Dockerfile CMD.
CMD ["gunicorn", "-w", "2", "-k", "uvicorn.workers.UvicornWorker", "-b", "0.0.0.0:8000", "app.main:app"]Related: Dockerizing Python - image layout
Stack versions: This page was written for Python 3.14.0 (stable 3.14, maintenance 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, and uv 0.6+.
Reviewed by Chris St. John·Last updated Jul 16, 2026