Python
Kubernetes
Production Ready
App Deployment
Cloud Native

Production ready Python apps on Kubernetes

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

A Python app becomes production-ready on Kubernetes when the container, runtime behavior, configuration, and operational signals all work together under failure and load. Shipping a Dockerfile and a Deployment is only the start. A real production setup needs predictable builds, health probes, graceful shutdown, resource limits, secure config handling, and observability that operators can trust.

Build a Minimal, Predictable Image

Your container should be small, reproducible, and explicit about how the app starts.

A simple FastAPI example:

dockerfile
1FROM python:3.12-slim
2
3WORKDIR /app
4COPY requirements.txt .
5RUN pip install --no-cache-dir -r requirements.txt
6
7COPY . .
8
9ENV PYTHONUNBUFFERED=1
10CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]

Key points:

  • pin dependency versions in requirements.txt
  • avoid development tools in the runtime image
  • log to stdout and stderr rather than to local files
  • keep the startup command explicit

For WSGI apps, use a real server such as Gunicorn rather than the development server.

Expose Health Signals Correctly

Kubernetes needs to know whether the app is alive and whether it is ready to receive traffic.

A typical deployment section looks like:

yaml
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4  name: python-app
5spec:
6  replicas: 3
7  selector:
8    matchLabels:
9      app: python-app
10  template:
11    metadata:
12      labels:
13        app: python-app
14    spec:
15      containers:
16        - name: python-app
17          image: my-registry/python-app:1.0.0
18          ports:
19            - containerPort: 8080
20          readinessProbe:
21            httpGet:
22              path: /health/ready
23              port: 8080
24          livenessProbe:
25            httpGet:
26              path: /health/live
27              port: 8080

Readiness protects traffic routing. Liveness helps recover stuck processes. Do not point both probes at a meaningless endpoint that always says "OK". They should reflect real application state.

Handle Shutdown Gracefully

Kubernetes terminates pods during rollout, scale-down, and node events. Your Python app must respond well to SIGTERM.

For example, if background work or database connections need cleanup, do it explicitly.

python
1from fastapi import FastAPI
2
3app = FastAPI()
4
5@app.get("/health/live")
6def live():
7    return {"status": "live"}
8
9@app.get("/health/ready")
10def ready():
11    return {"status": "ready"}

At the process level, use a server that handles graceful shutdown properly, and set termination grace periods in Kubernetes if requests need time to drain.

Set Resource Requests and Limits

Without resource settings, scheduling and cluster fairness become unreliable.

yaml
1resources:
2  requests:
3    cpu: "250m"
4    memory: "256Mi"
5  limits:
6    cpu: "1000m"
7    memory: "512Mi"

Requests influence scheduling. Limits cap peak usage. Python apps often need extra care with memory because leaks, large caches, or data-heavy workloads can cause sudden OOM kills.

Start with measurements, not guesses, and adjust from real usage.

Keep Configuration Out of the Image

Environment-specific values should come from ConfigMaps, Secrets, or a dedicated secret manager, not from hardcoded files baked into the container image.

yaml
1env:
2  - name: APP_ENV
3    value: production
4  - name: DATABASE_URL
5    valueFrom:
6      secretKeyRef:
7        name: python-app-secrets
8        key: database-url

This keeps the image reusable across environments and reduces accidental secret exposure.

Production Readiness Also Means Operations

A Python service in Kubernetes should be observable.

At minimum, plan for:

  • structured logs to stdout
  • metrics endpoints or exporters
  • tracing where latency matters
  • alerting on error rate, saturation, and restarts

If your app is invisible at runtime, Kubernetes will still restart pods, but operators will not know why the service is failing.

Security and Runtime Hygiene

Good defaults include:

  • run as a non-root user
  • use a read-only root filesystem if practical
  • keep the image patched and scanned
  • limit RBAC permissions
  • use network policies if the cluster supports them

Production readiness is not only about uptime. It is also about reducing avoidable attack surface.

Common Pitfalls

The most common mistake is using a development server in production. It may work under light load but fail badly under concurrency or restarts.

Another mistake is treating probes as boilerplate. Bad probes create false confidence or unnecessary restarts.

Teams also often forget graceful shutdown and then lose in-flight requests during rolling deployments.

Finally, do not call an app production-ready if it has no resource settings, no observability, and no secret-management plan. Kubernetes alone does not provide those by magic.

Summary

  • Production-ready Python on Kubernetes requires more than a working container.
  • Use a minimal image, a real application server, and explicit health probes.
  • Handle shutdown correctly so rollouts and rescheduling do not drop work unexpectedly.
  • Set resource requests and limits based on actual usage.
  • Treat configuration, security, and observability as part of the deployment design.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.