# Blue-Green-Deployment ohne Kubernetes: Implementierung auf Docker Compose mit Null-Ausfallzeit
Die Implementierung eines Blue-Green-Deployments ist auch ohne Orchestratoren wie Kubernetes möglich – Docker Compose, nginx und eine durchdachte Graceful-Shutdown-Logik reichen aus. Dieser Ansatz ist besonders relevant für Teams, die auf dedizierten Servern oder virtuellen Maschinen arbeiten, wo der Einsatz eines vollständigen Clusters aus wirtschaftlichen oder architektonischen Gründen unpraktikabel ist. Der Artikel beschreibt die technische Umsetzung des Continuous Deployments für Web-Services und Background-Worker unter Berücksichtigung der Besonderheiten der Nachrichtenverarbeitung und des Status-Managements.
Blue-Green-Architektur auf Docker Compose
In der grundlegenden Konfiguration wird jede Anwendung dupliziert: Es gibt zwei unabhängige Instanzen – blue und green. Beide werden als separate Services in docker-compose.prod.yml gestartet, aber nur eine erhält zu jedem Zeitpunkt Traffic. Die Weiterleitung übernimmt ein Reverse-Proxy (nginx im Beispiel), der während des Deployments die Upstream-Adresse umschaltet. Grundprinzip: Die neue Instanz wird vollständig gestartet und besteht Health Checks, bevor die alte gestoppt wird.
Die Konfiguration erfordert die explizite Angabe von Ports für jede Instanz:
web-blue:
ports:
- "127.0.0.1:8002:8000"
web-green:
ports:
- "127.0.0.1:8003:8000"
Das ermöglicht nginx den Zugriff auf die gewünschte Instanz über localhost und einen spezifischen Port. Diese Einrichtung vermeidet Konflikte und vereinfacht das Lifecycle-Management.
Umgang mit Background-Workern
Background-Prozesse (Worker), die Nachrichten aus einer Queue konsumieren (z. B. RabbitMQ), erfordern einen speziellen Ansatz. Ein einfaches Stoppen des Containers führt zu Nachrichtenverlust oder erneuter Verarbeitung bei nicht-idempotenten Operationen. Die Lösung ist die Implementierung eines Graceful Shutdowns auf Anwendungsebene.
Dies wird über eine Singleton-Klasse mit einer is_accepting-Flag umgesetzt. Vor der Verarbeitung jeder Aufgabe prüft der Worker diese Flag:
- Wenn
is_accepting == True– wird die Aufgabe ausgeführt. - Wenn
is_accepting == False– wird die Nachricht mitrequeue=Truezurück in die Queue gestellt.
Bei Erhalt des SIGTERM-Signals wird die Flag auf False gesetzt, woraufhin die Anwendung auf das Abschließen aller laufenden Aufgaben wartet (mit einem Puffer von 5–10 Sekunden) und dann herunterfährt. So gehen keine Nachrichten verloren und es entstehen keine Dateninkonsistenzen.
Wichtige Nuancen:
- Bei Multi-Process-Workern (z. B. ProcessPoolExecutor) muss der
is_accepting-Status für alle Child-Prozesse zugänglich sein. Andernfalls verarbeiten einige Consumer weiterhin neue Aufgaben. - Nicht-idempotente Operationen erfordern zusätzliche Schutzmaßnahmen: Erneute Verarbeitung kann die Datenintegrität zerstören.
- Ein verteilter Flag (z. B. in Redis) verkompliziert die Architektur, kann aber in Systemen mit hoher Last gerechtfertigt sein.
Deployment-Skript: Schritt-für-Schritt-Logik
Das Deployment-Skript automatisiert den Wechsel zwischen den Instanzen. Die Logik ist für Web-Services und Worker gleich, aber mit unterschiedlichen Einstiegspunkten.
Hauptphasen:
- Ermittlung der aktiven Instanz (durch Analyse der nginx-Konfiguration oder der Liste laufender Container).
- Starten der inaktiven Instanz (
docker compose up -d). - Überprüfung der Bereitschaft der neuen Instanz via Health Check (bis zu 30 Versuche mit 2-Sekunden-Intervallen).
- Aktualisierung der nginx-Konfiguration und Ausführen von
nginx -s reload. - Warten auf das Abschließen aller aktiven HTTP-Anfragen (meist 5 Sekunden).
- Stoppen der alten Instanz (
docker compose stop).
Beispiel für einen Web-Service:
echo "server 127.0.0.1:${INACTIVE_PORT};" > "$UPSTREAM_CONF"
nginx -t && nginx -s reload
sleep 5
$COMPOSE stop web-${ACTIVE}
Diese Abfolge stellt sicher, dass Traffic nie auf einen unvorbereiteten Service geleitet wird und die alte Instanz erst nach vollständigem Wechsel herunterfährt.
Kompatibilität von Datenbankschemata und Migrationen
Eine der größten Herausforderungen beim Blue-Green-Deployment ist der parallele Betrieb zweier Anwendungsversionen gegen dieselbe Datenbank. Um Fehler zu vermeiden, müssen alle Migrationen rückwärtskompatibel sein.
Empfohlener Ansatz – zweistufiges Update:
- Erstes Deployment: Entfernen der Nutzung des veralteten Feldes/Tabellen im Code, aber Beibehalten der Struktur in der Datenbank. Beide Versionen – neu und alt – funktionieren korrekt.
- Zweites Deployment (nach vollständigem Traffic-Wechsel): Durchführen der Migration zum Entfernen ungenutzter Schema-Elemente.
Das erhöht die Anzahl der Operationen, eliminiert aber das Risiko, dass die alte Instanz aufgrund von Schema-Inkompatibilitäten abstürzt.
Wichtige Punkte
- Blue-Green-Deployment auf Docker Compose ist ohne Kubernetes möglich, erfordert aber manuelles Management von Instanzen und Proxy.
- Graceful Shutdown für Worker ist entscheidend – ohne ihn können Nachrichten verloren gehen oder dupliziert werden.
- Alle Datenbank-Migrationen müssen rückwärtskompatibel sein; Feldentfernungen erfordern einen zweistufigen Ansatz.
- Health Check der neuen Instanz ist vor dem Traffic-Wechsel zwingend erforderlich.
- Nginx-Konfiguration muss atomar aktualisiert und mit
nginx -tvalidiert werden.
— Editorial Team
Noch keine Kommentare.