CI/CD
.yml
GitLab · Magento · Zero Downtime · Realismus · Deployment-Strategie
Zero-Downtime in Magento realistisch:
Was geht ohne Ausfall – und was nicht

Zero-Downtime wird versprochen und selten klar definiert. Dieser Artikel erklärt ehrlich, wo der Symlink-Switch wirklich ohne Ausfallzeit funktioniert – und wo Datenbankmigrationen unvermeidlich ein kurzes Wartungsfenster erfordern.

13 Min. Lesezeit Zero Downtime · Symlink · setup:upgrade · DB-Migration · Maintenance-Mode Magento 2.4 · PHP 8.4 · GitLab CI/CD

1. Was Zero-Downtime wirklich bedeutet

Zero-Downtime bedeutet nicht, dass kein einziger Prozess neu gestartet wird oder kein einziger Request länger dauert als gewöhnlich. Es bedeutet, dass der Shop für Endnutzer durchgehend erreichbar ist und keine sichtbaren Fehlerzustände auftreten. Der Symlink-Switch in einem Magento-Deployment ist atomar: Der Webserver zeigt nach dem Switch auf ein anderes Verzeichnis, ohne dass eine einzige Anfrage mit einem 503 beantwortet wird. Das ist echter Zero-Downtime auf Dateiebene.

Was Zero-Downtime nicht löst: die Zeitspanne zwischen dem Moment, in dem der neue Code aktiv ist, und dem Moment, in dem der Cache, der Suchindex und die Queue-Consumer vollständig auf den neuen Zustand aufgeholt haben. In dieser Phase können Nutzer inkonsistente Zustände sehen – veraltete Cache-Inhalte, noch nicht indexierte Produkte, Queue-Nachrichten, die mit dem alten Code verarbeitet wurden. Diese Inkonsistenzperiode ist kürzer als ein Wartungsfenster, aber sie ist real. Wer Zero-Downtime verspricht, ohne diese Periode zu adressieren, liefert eine unvollständige Wahrheit.

Echtes Zero-Downtime für Magento ist erreichbar, aber es erfordert klare Entscheidungen pro Release-Typ. Reine Code-Releases ohne Datenbankmigrationen können vollständig ohne Downtime deployt werden. Releases mit Datenbankmigrationen benötigen entweder die Expand-and-Contract-Strategie oder ein kurzes, definiertes Wartungsfenster. Dieses Kapitel erklärt, welche Releases welche Strategie erfordern.

2. Was wirklich ohne Downtime geht

Ohne Downtime deployt werden können: reine Code-Änderungen ohne Datenbankmigrationen, CSS- und JavaScript-Updates, Template-Änderungen, neue PHP-Logik, die das bestehende Datenbankschema nicht berührt, Konfigurationsänderungen, die über Magento-Konfigurationsstruktur verwaltet werden. Für all diese Release-Typen ist der Symlink-Switch ausreichend. Der alte Code und der neue Code sind gleichzeitig auf dem Dateisystem vorhanden; der Switch bestimmt, welchen Code der Webserver für neue Requests verwendet.

Wichtig für echtes Zero-Downtime: Der neue Code muss mit dem bestehenden Datenbankschema kompatibel sein. Wenn ein neues Modul eine neue Datenbankspalte voraussetzt, aber setup:upgrade noch nicht ausgeführt wurde, wird der neue Code nach dem Symlink-Switch sofort fehlschlagen. Das ist kein Zero-Downtime-Deployment mehr. Die Kompatibilitätsprüfung zwischen neuem Code und aktuellem Datenbankschema muss Teil der Build- oder Pre-Deploy-Stage sein, nicht eine Hoffnung nach dem Switch.

3. Was nicht ohne Downtime geht

Es gibt Deployment-Szenarien, in denen Downtime unvermeidlich ist – zumindest ohne aufwändige Expand-and-Contract-Strategien. Das erste Szenario sind destruktive Datenbankänderungen: Spalten umbenennen, Spalten löschen, Tabellentypen ändern. Diese Operationen können nicht rückwärtskompatibel durchgeführt werden, weil der alte Code, der möglicherweise noch während des Deployments auf die Datenbank zugreift, die umbenannte oder gelöschte Spalte voraussetzt.

Das zweite Szenario sind komplexe Datentransformationen: das Befüllen neuer Spalten aus bestehenden Daten, das Aufteilen von Tabellen, das Zusammenführen von Tabellen. Diese Operationen können bei großen Datenmengen Minuten bis Stunden dauern. Während dieser Zeit ist die Datenbank in einem halbfertigen Zustand, der weder vollständig zum alten noch zum neuen Code kompatibel ist. Das dritte Szenario sind Magento-Kern-Updates mit eigenem Schema-Upgrade, bei denen setup:upgrade nicht übersprungen werden kann und signifikante Zeit beansprucht.

4. setup:upgrade: der kritische Schritt

bin/magento setup:upgrade ist der Schritt, der in Magento-Deployments am häufigsten Downtime verursacht. Er führt alle ausstehenden Datenbankmigrationen aus, aktualisiert das Schema und modifiziert die Konfigurationstabellen. Bei einem Magento-Kern-Update oder einem großen Modul-Update kann dieser Schritt fünf bis fünfzehn Minuten dauern. Während setup:upgrade läuft, sind Datenbankschema und Code inkompatibel – neuer Code mit altem Schema oder alter Code mit neuem Schema.

Die einzig sichere Strategie für setup:upgrade mit echtem Downtime-Risiko ist der Maintenance-Mode. Dieser verhindert, dass Requests die Anwendung während der Migration erreichen. Der Maintenance-Mode muss vor dem setup:upgrade aktiviert und sofort nach dem Ende deaktiviert werden. Ein setup:upgrade ohne Maintenance-Mode bei Schema-ändernden Migrationen ist kein kontrollierter Prozess, sondern Glückssache.

# Deploy job with controlled maintenance window for DB migrations
deploy:production:with-migration:
  stage: deploy
  variables:
    # Set HAS_DB_MIGRATION=1 for releases with schema changes
    HAS_DB_MIGRATION: "0"
  script:
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
    - echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
    - RELEASE_ID=$(date +%Y%m%d-%H%M%S)
    - |
      ssh "$DEPLOY_USER@$DEPLOY_HOST" bash -s << SSH
      set -euo pipefail
      RELEASE_PATH="$DEPLOY_PATH/releases/$RELEASE_ID"
      mkdir -p "\$RELEASE_PATH"
      SSH
    - rsync -az --delete ./ "$DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_PATH/releases/$RELEASE_ID/"
    - |
      ssh "$DEPLOY_USER@$DEPLOY_HOST" bash -s << 'SSH'
      set -euo pipefail
      RELEASE_PATH="$DEPLOY_PATH/releases/$RELEASE_ID"
      # Link shared resources
      ln -sfn "$DEPLOY_PATH/shared/app/etc/env.php" "$RELEASE_PATH/app/etc/env.php"
      ln -sfn "$DEPLOY_PATH/shared/pub/media" "$RELEASE_PATH/pub/media"
      # Enable maintenance mode ONLY for releases with DB migrations
      if [ "$HAS_DB_MIGRATION" = "1" ]; then
        cd "$DEPLOY_PATH/current"
        bin/magento maintenance:enable
        echo "Maintenance mode enabled — running DB migration"
        # Switch symlink to new release
        ln -sfn "$RELEASE_PATH" "$DEPLOY_PATH/current"
        cd "$DEPLOY_PATH/current"
        bin/magento setup:upgrade --keep-generated
        bin/magento maintenance:disable
        echo "Migration complete — maintenance mode disabled"
      else
        # Zero-downtime path: no maintenance needed
        ln -sfn "$RELEASE_PATH" "$DEPLOY_PATH/current"
        cd "$DEPLOY_PATH/current"
        echo "No DB migration — zero-downtime deploy complete"
      fi
      bin/magento cache:flush
      SSH
  when: manual
  only:
    - tags

5. Expand-and-Contract: DB-Migrationen ohne Downtime

Die Expand-and-Contract-Strategie ist der Weg, Datenbankmigrationen ohne Maintenance-Mode durchzuführen. Das Prinzip: Jede Datenbankänderung wird in zwei separate Releases aufgeteilt. Das erste Release (Expand) erweitert das Schema rückwärtskompatibel – neue Spalten hinzufügen, alte Spalten behalten. Der Code beider Versionen (alt und neu) ist mit dem erweiterten Schema kompatibel. Das zweite Release (Contract) entfernt die alten Spalten oder macht die nicht mehr benötigten Änderungen, sobald kein Code mehr auf die alten Spalten zugreift.

Diese Strategie ist aufwändiger als ein einfaches setup:upgrade mit Maintenance-Mode. Sie erfordert, dass Entwickler Datenbankmigrationen explizit als "Expand" oder "Contract" klassifizieren und entsprechend planen. Für Magento-Core-Updates ist sie meist nicht anwendbar, weil die Core-Migrationen nicht unter der eigenen Kontrolle liegen. Für eigene Module und eigene Schemaänderungen ist sie der bevorzugte Weg, wenn Zero-Downtime ein nicht verhandelbares Anforderung ist.

6. Maintenance-Mode: wann er wirklich notwendig ist

Der Maintenance-Mode in Magento ist kein Zeichen für schlechtes Deployment-Design. Er ist ein explizites Sicherheitsnetz für Situationen, in denen die Anwendung vorübergehend in einem inkonsistenten Zustand ist. Er sollte sparsam, gezielt und mit einer klar definierten Zeitspanne eingesetzt werden. Ein Maintenance-Mode von 30 Sekunden für ein kontrollierten Datenbankschritt ist akzeptabel. Ein Maintenance-Mode von 30 Minuten für einen unorganisierten Build-Prozess ist es nicht.

Die Pipeline sollte den Maintenance-Mode als explizit zu setzende Variable behandeln: HAS_DB_MIGRATION=1 aktiviert ihn, HAS_DB_MIGRATION=0 (der Standard) lässt ihn aus. Diese Entscheidung muss vor jedem Deployment bewusst getroffen werden, dokumentiert sein und vom Team kommuniziert werden. Ein Maintenance-Mode, der automatisch und undiskriminiert bei jedem Deployment aktiviert wird, ist ein Zeichen dafür, dass der Deployment-Prozess nicht verstanden wird – nicht dafür, dass er sicher ist.

7. Pipeline-Strategie je nach Release-Typ

Die GitLab-Pipeline sollte verschiedene Deploy-Jobs für verschiedene Release-Typen anbieten. Ein deploy:production:no-migration-Job für reine Code-Releases, der vollständig ohne Maintenance-Mode auskommt. Ein deploy:production:with-migration-Job für Releases mit Datenbankmigrationen, der Maintenance-Mode aktiviert und setup:upgrade kontrolliert ausführt. Beide Jobs existieren parallel in der Pipeline; das Team wählt vor dem Deploy, welcher Pfad dem aktuellen Release entspricht.

Diese Trennung erzwingt die bewusste Entscheidung über den Deployment-Typ. Sie verhindert, dass ein Release mit Datenbankmigrationen versehentlich über den Zero-Downtime-Pfad deployt wird und die Anwendung in einen inkonsistenten Zustand versetzt. Sie verhindert auch, dass ein einfacher Code-Release unnötig den Maintenance-Mode aktiviert und Nutzer aussperrt. Die Pipeline ist der Ort, wo diese Entscheidung strukturell abgesichert wird.

8. Monitoring nach dem Deploy: Was überwacht werden sollte

Nach jedem Deployment – ob mit oder ohne Maintenance-Mode – muss das Monitoring für mindestens 30 Minuten erhöhte Aufmerksamkeit erhalten. Die wichtigsten Metriken direkt nach dem Deploy sind: HTTP-Error-Rate (5xx), Datenbankabfragezeiten, PHP-OPcache-Trefferate (sinkt nach Deploy, steigt danach wieder), Queue-Consumer-Status und Suchindex-Status. Anomalien in diesen Metriken in den ersten 30 Minuten nach dem Deploy deuten auf Probleme hin, die schnell einen Rollback erfordern können.

Ein Verify-Job in der Pipeline deckt die sofortige Prüfung ab. Das Monitoring deckt die anhaltende Beobachtung in den Minuten nach dem Verify-Job ab. Beides zusammen gibt dem Team die Sicherheit, ein Deployment als abgeschlossen und stabil zu erklären. Ohne Monitoring nach dem Deploy gibt es keine Garantie, dass das neue Release in der Produktion korrekt verhält – nur eine Hoffnung.

9. Deployment-Typen im Vergleich

Die folgende Tabelle zeigt die drei wichtigsten Deployment-Typen in Magento-Projekten mit ihren jeweiligen Eigenschaften. Sie macht deutlich, dass Zero-Downtime kein binäres Konzept ist, sondern von der Art der Änderungen abhängt.

Release-Typ Maintenance-Mode setup:upgrade Typische Downtime
Reiner Code-Release Nicht nötig Nicht nötig 0 Sekunden (echter Zero-Downtime)
Neues Modul (additive DB) Optional (Expand first) Empfohlen 0–30 Sekunden mit Expand-Strategie
Destruktive DB-Änderung Notwendig Notwendig 30 Sek.–15 Min. (je nach Datenmenge)
Magento-Kern-Update Empfohlen Notwendig 5–15 Min. (abhängig von Magento-Version)
CSS/JS/Template-Update Nicht nötig Nicht nötig 0 Sekunden (echter Zero-Downtime)

Die Tabelle macht deutlich: Echter Zero-Downtime ist in Magento für die häufigsten Release-Typen – reine Code-Releases und Template-Updates – vollständig erreichbar. Für Releases mit Datenbankmigrationen ist eine Entscheidung notwendig, die vom Typ der Migration abhängt. Diese Entscheidung muss pro Release bewusst getroffen und in der Pipeline strukturell abgesichert werden.

10. Zusammenfassung

Zero-Downtime in Magento realistisch verstehen bedeutet, zwischen Release-Typen zu unterscheiden und für jeden den passenden Deployment-Pfad zu wählen. Reine Code-Releases, Template-Updates und CSS/JS-Änderungen können vollständig ohne Downtime deployt werden – der Symlink-Switch ist der einzige Schritt, der für Nutzer sichtbar ist. Releases mit Datenbankmigrationen erfordern entweder die Expand-and-Contract-Strategie für echtes Zero-Downtime oder ein kurzes, klar definiertes Wartungsfenster mit Maintenance-Mode.

Die GitLab-Pipeline setzt diese Unterscheidung strukturell um: Verschiedene Deploy-Jobs für verschiedene Release-Typen, explizite Variablen für Maintenance-Mode und DB-Migrationen, und Verify-Jobs, die nach dem Deploy den Zustand der Anwendung prüfen. Zero-Downtime ist kein Marketing-Versprechen, sondern das Ergebnis konkreter, realistisch geplanter Deployment-Entscheidungen.

Zero-Downtime in Magento — Das Wichtigste auf einen Blick

Was geht ohne Downtime

Reine Code-Releases, Template-Updates, CSS/JS-Änderungen ohne Datenbankmigrationen – Symlink-Switch reicht aus.

Was Downtime erfordert

Destruktive Datenbankmigrationen, Magento-Kern-Updates mit Schema-Upgrade, komplexe Datentransformationen.

Expand-and-Contract

Für additive DB-Migrationen: Expand-Release fügt neue Spalten hinzu, Contract-Release entfernt alte. Kein Maintenance nötig.

Pipeline-Strategie

Zwei Deploy-Jobs: ohne Maintenance (Standard), mit Maintenance (bei DB-Migration). HAS_DB_MIGRATION als steuernde Variable.

11. FAQ: Zero-Downtime in Magento realistisch

1Kann Magento vollständig ohne Downtime deployt werden?
Für reine Code-Releases ohne DB-Migrationen: ja. Der Symlink-Switch ist atomar. Bei destruktiven Datenbankmigrationen ist oft ein kurzes Wartungsfenster unvermeidlich.
2setup:upgrade bei jedem Deployment?
Nein. Nur bei neuen Datenbankmigrationen. Reine Code-Releases können setup:upgrade überspringen. --keep-generated beschleunigt es, wenn generierter Code im Artefakt ist.
3Was ist die Expand-and-Contract-Strategie?
Zwei-Schritt-Migration: Expand fügt neue Spalten hinzu (additiv). Contract entfernt alte Spalten in einem späteren Release. Kein Maintenance-Mode nötig.
4Maximale Dauer des Maintenance-Mode?
Unter 5 Minuten für kontrollierte DB-Migrationen. Längere Fenster deuten auf nicht optimierte Migrationen hin. Außerhalb der Stoßzeiten planen.
5Warum manchmal Maintenance besser als Zero-Downtime?
Bei destruktiven DB-Migrationen schützt ein kurzer Maintenance die Datenintegrität. Erzwungenes Zero-Downtime kann zu inkonsistenten Zuständen führen.
6Wie erkenne ich ausstehende DB-Migrationen?
bin/magento setup:db:status zeigt ausstehende Migrationen. In der Pipeline als pre-deploy-Job ausführen, um den Deployment-Typ automatisch zu bestimmen.
7Neuer Code vor setup:upgrade aktiviert?
Wenn neuer Code eine neue Spalte voraussetzt, die noch nicht existiert, schlägt er mit Datenbankfehlern fehl. Häufigster Fehler bei Releases ohne Maintenance.
8Wie schnell ist der Symlink-Switch?
Millisekunden – ein einziger Kernel-Syscall. Neue Requests nach dem Switch greifen sofort auf das neue Release zu. Schnellste Methode für Codeübergang.
9Hilft --keep-generated bei der Downtime?
Ja. Überspringt DI-Compile in setup:upgrade, weil generierter Code im Artefakt enthalten ist. Reduziert Laufzeit von setup:upgrade deutlich.
10Wie geplante Wartungsfenster kommunizieren?
Magento zeigt konfigurierbare Wartungsseite. Außerhalb der Stoßzeiten planen. Vorankündigung per Newsletter oder Social Media bei größeren Updates.

Kernaussage: Zero Downtime ist kein binärer Zustand

Die meisten Magento-Shops profitieren davon, häufige, unkritische Deploys (Code-Änderungen, neue Features) konsequent ohne Downtime durchzuführen — und für seltene, kritische Deploys (Core-Updates, destruktive Migrationen) ein kurzes, kommuniziertes Wartungsfenster einzuplanen. Das ist realistischer Zero-Downtime-Betrieb.

Wer Zero Downtime als absolutes Ziel für jeden Deploy verfolgt, investiert unverhältnismäßig viel in Infrastruktur. Der pragmatische Mittelweg — differenziert nach Änderungstyp — ist der nachhaltigste Ansatz für produktive Magento-Teams.