Introduction
Kubernetes (K8s) is the industry-standard container orchestration platform. In the Orbital multi-tenant platform, we used Kubernetes on AWS EKS to achieve zero-downtime rolling deployments, automatic scaling, and self-healing infrastructure. This guide walks through containerising a Django app and deploying it on K8s.
Step 1 โ Containerise Your Application
First, create a production-ready Dockerfile. Use multi-stage builds and a non-root user for security:
FROM python:3.11-slim AS builder WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt FROM python:3.11-slim WORKDIR /app COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages COPY . . # Run as non-root RUN adduser --disabled-password appuser USER appuser EXPOSE 8000 CMD ["gunicorn", "myproject.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "3"]
Step 2 โ Write a Kubernetes Deployment
A Deployment manages your pods, handles rolling updates, and restarts failed containers automatically:
apiVersion: apps/v1
kind: Deployment
metadata:
name: django-app
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: django-app
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
template:
metadata:
labels:
app: django-app
spec:
containers:
- name: django
image: myorg/django-app:latest
ports:
- containerPort: 8000
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: django-secrets
key: database-url
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health/
port: 8000
initialDelaySeconds: 15
periodSeconds: 20
๐ก Tip: Always set resources.requests and resources.limits. Without them, a runaway pod can starve other services in the same cluster โ a critical issue in multi-tenant environments.
Step 3 โ Expose with a Service & Ingress
apiVersion: v1
kind: Service
metadata:
name: django-service
spec:
selector:
app: django-app
ports:
- port: 80
targetPort: 8000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: django-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
rules:
- host: api.myapp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: django-service
port:
number: 80
Step 4 โ Store Secrets Safely
# Create secret from .env file kubectl create secret generic django-secrets \ --from-env-file=.env.production \ --namespace=production # Verify kubectl get secrets -n production
Step 5 โ Deploy & Roll Out
# Apply manifests kubectl apply -f k8s/ # Monitor rollout kubectl rollout status deployment/django-app -n production # Roll back if needed kubectl rollout undo deployment/django-app -n production
Conclusion
With Kubernetes, your Python app gains production-grade resilience: automatic restarts on failure, rolling zero-downtime deployments, and horizontal scaling under load. Combined with the CI/CD pipeline from our GitHub Actions article, you have a complete modern DevOps workflow from code commit to live cluster.