- Authors

- Name
- Phillip Pham
- @ddppham
Python Django auf Kubernetes deployen
TL;DR
Django auf Kubernetes erfordert ein Multi-Stage Dockerfile mit Gunicorn als WSGI-Server, WhiteNoise für statische Dateien und separate Deployments für Celery-Worker. ConfigMaps und Secrets verwalten die Konfiguration, während Liveness- und Readiness-Probes die Verfügbarkeit sicherstellen.
Django ist eines der verbreitetsten Python-Frameworks für Webanwendungen. Der Betrieb auf Kubernetes bringt Skalierbarkeit, Rolling Updates und automatisches Self-Healing. Dieser Guide zeigt den vollständigen Weg vom Dockerfile bis zum laufenden Cluster.
Multi-Stage Dockerfile für Django
Ein optimiertes Dockerfile trennt Build- und Runtime-Phase. So bleibt das finale Image klein und enthält keine Build-Tools.
# Build-Stage
FROM python:3.12-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
# Runtime-Stage
FROM python:3.12-slim
RUN groupadd -r django && useradd -r -g django django
WORKDIR /app
COPY /install /usr/local
COPY . .
RUN python manage.py collectstatic --noinput
USER django
EXPOSE 8000
CMD ["gunicorn", "myproject.wsgi:application", \
"--bind", "0.0.0.0:8000", \
"--workers", "3", \
"--timeout", "120"]
Wichtige Details: Der --no-cache-dir-Flag bei pip spart Speicher im Image. Gunicorn ersetzt den Django-Entwicklungsserver und bietet Multi-Worker-Processing. Die Anzahl der Worker richtet sich nach der Formel (2 × CPU-Kerne) + 1.
Statische Dateien mit WhiteNoise
Django serviert in Production keine statischen Dateien selbst. WhiteNoise löst das ohne separaten Nginx:
# settings.py
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
# ... weitere Middleware
]
STATIC_URL = '/static/'
STATIC_ROOT = '/app/staticfiles'
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
WhiteNoise komprimiert Dateien automatisch mit Gzip und Brotli und setzt Cache-Header. Für die meisten Django-Projekte reicht das aus.
Konfiguration mit ConfigMap und Secret
Umgebungsvariablen gehören nicht ins Image. Kubernetes verwaltet sie über ConfigMaps und Secrets:
apiVersion: v1
kind: ConfigMap
metadata:
name: django-config
data:
DJANGO_SETTINGS_MODULE: "myproject.settings.production"
ALLOWED_HOSTS: "*.kubernetes-administration.de"
DB_HOST: "postgres-service"
DB_PORT: "5432"
CELERY_BROKER_URL: "redis://redis-service:6379/0"
---
apiVersion: v1
kind: Secret
metadata:
name: django-secret
type: Opaque
stringData:
SECRET_KEY: "dein-geheimer-schluessel-hier"
DB_PASSWORD: "sicheres-passwort"
In settings.py lesen Sie die Werte per os.environ:
import os
SECRET_KEY = os.environ['SECRET_KEY']
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'HOST': os.environ.get('DB_HOST', 'localhost'),
'PORT': os.environ.get('DB_PORT', '5432'),
'PASSWORD': os.environ['DB_PASSWORD'],
}
}
Django Deployment mit Health Checks
Das Deployment referenziert ConfigMap und Secret und definiert Liveness- und Readiness-Probes:
apiVersion: apps/v1
kind: Deployment
metadata:
name: django-web
spec:
replicas: 3
selector:
matchLabels:
app: django-web
template:
metadata:
labels:
app: django-web
spec:
containers:
- name: django
image: registry.example.com/django-app:1.0.0
ports:
- containerPort: 8000
envFrom:
- configMapRef:
name: django-config
- secretRef:
name: django-secret
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /healthz/
port: 8000
initialDelaySeconds: 10
periodSeconds: 15
readinessProbe:
httpGet:
path: /ready/
port: 8000
initialDelaySeconds: 5
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: django-service
spec:
selector:
app: django-web
ports:
- port: 80
targetPort: 8000
type: ClusterIP
Für die Health-Check-Endpoints genügt eine einfache Django-View:
# health/views.py
from django.http import JsonResponse
from django.db import connection
def healthz(request):
return JsonResponse({"status": "ok"})
def ready(request):
try:
connection.ensure_connection()
return JsonResponse({"status": "ready"})
except Exception:
return JsonResponse({"status": "not ready"}, status=503)
Die Readiness-Probe prüft die Datenbankverbindung. Solange die DB nicht erreichbar ist, leitet der Service keinen Traffic an den Pod.
Celery-Worker als separates Deployment
Asynchrone Tasks gehören in eigene Pods. Celery-Worker teilen sich das gleiche Image, starten aber mit einem anderen Befehl:
apiVersion: apps/v1
kind: Deployment
metadata:
name: celery-worker
spec:
replicas: 2
selector:
matchLabels:
app: celery-worker
template:
metadata:
labels:
app: celery-worker
spec:
containers:
- name: celery
image: registry.example.com/django-app:1.0.0
command: ["celery", "-A", "myproject", "worker",
"--loglevel=info", "--concurrency=4"]
envFrom:
- configMapRef:
name: django-config
- secretRef:
name: django-secret
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: "1"
memory: 1Gi
livenessProbe:
exec:
command:
- celery
- -A
- myproject
- inspect
- ping
initialDelaySeconds: 30
periodSeconds: 60
Celery-Worker brauchen typischerweise mehr Ressourcen als Web-Pods. Die exec-Probe prüft, ob der Worker noch auf Celery-Kommandos reagiert. Skalieren Sie Worker unabhängig von den Web-Pods je nach Queue-Länge.
| Komponente | CPU Request | Memory Request | Replicas |
|---|---|---|---|
| Django Web | 250m | 256Mi | 3 |
| Celery Worker | 500m | 512Mi | 2 |
| Celery Beat | 100m | 128Mi | 1 |
Datenbank-Migrationen ausführen
Migrationen laufen als Kubernetes Job vor dem Deployment:
apiVersion: batch/v1
kind: Job
metadata:
name: django-migrate
spec:
template:
spec:
containers:
- name: migrate
image: registry.example.com/django-app:1.0.0
command: ["python", "manage.py", "migrate", "--noinput"]
envFrom:
- configMapRef:
name: django-config
- secretRef:
name: django-secret
restartPolicy: Never
backoffLimit: 3
Integrieren Sie den Job in Ihre CI/CD-Pipeline, sodass Migrationen automatisch vor jedem Deployment laufen.
FAQ
Warum Gunicorn statt dem Django-Entwicklungsserver?
Der Django-Entwicklungsserver ist single-threaded und nicht für Production gedacht. Gunicorn startet mehrere Worker-Prozesse, verarbeitet Requests parallel und kann bei einem Crash einzelne Worker automatisch neu starten.
Wie viele Gunicorn-Worker sollte ich konfigurieren?
Die Faustregel lautet (2 × CPU-Kerne) + 1. Bei einem Pod mit 500m CPU-Limit sind 2-3 Worker sinnvoll. Zu viele Worker verbrauchen unnötig RAM und führen zu CPU-Throttling.
Brauche ich einen separaten Nginx vor Gunicorn?
Mit WhiteNoise für statische Dateien und einem Kubernetes Ingress Controller ist ein separater Nginx in den meisten Fällen nicht notwendig. Der Ingress übernimmt TLS-Terminierung und Routing.
Wie deploye ich Django-Migrationen ohne Downtime?
Führen Sie Migrationen als Kubernetes Job vor dem Deployment aus. Verwenden Sie nur additive Migrationen (neue Spalten mit Default-Werten), damit alte und neue Code-Versionen gleichzeitig funktionieren.
Wie skaliere ich Celery-Worker automatisch?
Nutzen Sie KEDA (Kubernetes Event-Driven Autoscaler) mit einem Redis- oder RabbitMQ-Trigger. KEDA skaliert Worker basierend auf der Queue-Länge, nicht auf CPU-Auslastung.
Legacy zu Kubernetes migrieren?
Wir begleiten Ihre Migration von VMs zu Containern – ohne Produktionsausfall. Erfahrung aus 50+ Migrationsprojekten.
Kubernetes-Beratung gesucht?
Wir helfen deutschen Unternehmen bei der Kubernetes-Implementierung, Migration und Optimierung. DSGVO-konform und praxiserprobt.
📖 Verwandte Artikel
Weitere interessante Beiträge zu ähnlichen Themen
.NET-Anwendungen auf Kubernetes containerisieren
.NET- und ASP.NET-Core-Anwendungen für Kubernetes containerisieren: Multi-Stage Dockerfile, Health Checks, Kestrel-Konfiguration und komplette Manifeste.
Node.js auf Kubernetes: Express-App deployen
Express-Apps auf Kubernetes deployen mit Multi-Stage Dockerfile, Graceful Shutdown, Resource Limits und HPA für stabile Production-Cluster.
Kubernetes Automotive ASPICE 2026: Container für SDV und Compliance
Entdecken Sie, wie Kubernetes Automotive ASPICE 2026 Standards für die SDV-Entwicklung & Compliance revolutioniert. Effiziente Entwicklung, Tests und sichere Prozesse für OEMs in Deutschland – ein entscheidender Schritt für Kubernetes Compliance Deutschland.
ArgoCD ApplicationSets: Multi-App Deployment Patterns
ArgoCD ApplicationSets automatisieren Multi-App und Multi-Cluster Deployments mit Generatoren. Praxis-Patterns für Git, Cluster und Matrix.
BSI-Grundschutz für Kubernetes-Cluster umsetzen
BSI IT-Grundschutz für Kubernetes umsetzen: Baustein SYS.1.6 Containerisierung mit Pod Security Standards, Audit-Logging und Netzwerksegmentierung.