FastAPI · Lesson 15 of 15
Production: Docker and Observability
Uvicorn workers, health checks, structured logs and tracing.
- Advanced
- 16 min read
- 3 objectives
Before this lessonLesson 14: Custom OpenAPI and Docs
What you will learn
- Write a Dockerfile
- Expose /health
- Log request ids
Your Progress
0 of 15 lessons 0%
- Lessons0 / 15
- Completed0
- Est. time left~ 4 hours
Create a free account to keep your progress on every device.
Production FastAPI is an ASGI server, several workers, a reverse proxy, and enough observability to debug the next outage.
Docker
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "2"]For a lot of blocking I/O, more workers help. For a lot of async def waiting on the network, fewer workers and a bigger event loop often win. Measure.
Health and readiness
@app.get("/health", include_in_schema=False)
def health(db: Session = Depends(get_db)):
db.execute(text("SELECT 1"))
return {"status": "ok"}Structured logs
import logging, json
class JsonLog(logging.Formatter):
def format(self, rec):
return json.dumps({"level": rec.levelname, "msg": rec.getMessage()})
logging.basicConfig(level="INFO")
logging.getLogger().handlers[0].setFormatter(JsonLog())- Put a request id on every log line (middleware).
- Do not log tokens, passwords or full request bodies.
- Export OpenTelemetry traces if you have more than one service.
