CI/CD
.yml
GitLab · Environments · Staging · Production · Freigaben
GitLab Environments, Manual Jobs
und Freigaben für Staging und Production

Ein Deployment auf Staging darf automatisch passieren; ein Deployment auf Production braucht eine bewusste Freigabe. GitLab Environments, when: manual und Deployment-Approvals implementieren genau dieses Freigabemodell – mit sichtbarer Deployment-History und variablen-scopingbasierter Umgebungsisolierung.

14 Min. Lesezeit Environments · when:manual · Approvals · Scoping · Deployment-History GitLab · Magento 2.4 · E-Commerce

1. Was GitLab Environments sind und warum sie für Magento wichtig sind

GitLab Environments sind benannte Zielumgebungen für Deployments, die in der Pipeline-Konfiguration deklariert werden. Wenn ein Job environment: name: staging enthält, verknüpft GitLab den Job mit der Staging-Umgebung und protokolliert jeden Deployment-Vorgang in der Umgebungs-History. Das Ergebnis ist eine übersichtliche Übersicht im GitLab-Interface, die zeigt, welche Version aktuell auf welcher Umgebung deployed ist, wer den Deploy ausgelöst hat und wann er stattgefunden hat.

Für Magento-Projekte sind Environments besonders wertvoll, weil der Weg von einem Feature bis zur Production mehrere Umgebungen durchläuft: Development (lokal), Staging (geteilte Test-Umgebung), Pre-Production (optional, produktionsnahe Tests) und Production. GitLab Environments machen diesen Weg sichtbar – mit einer URL zum aktuell deployten Stand, die direkt in der Umgebungs-Übersicht verlinkt ist.

Ein weiterer Vorteil von deklarierten Environments ist die Integration mit variablen Scoping: Variablen können für eine spezifische Umgebung konfiguriert werden und stehen nur in Jobs zur Verfügung, die diese Umgebung referenzieren. So ist es technisch unmöglich, dass ein Staging-Deploy-Job Production-Credentials bekommt, selbst wenn Variablen-Namen identisch sind. Das ist eine strukturelle Sicherheitsmaßnahme, die ohne deklarierten Environment-Scope nicht möglich ist.

2. Environments in .gitlab-ci.yml konfigurieren

Die Basis-Konfiguration eines Environments in .gitlab-ci.yml besteht aus dem Namen und optional einer URL. Der Name muss konsistent mit der GitLab-Umgebungs-Konfiguration und dem Variable-Scope sein. Für Magento-Projekte sind typische Umgebungsnamen staging und production. Wenn ein Kunde mehrere Shops hat, können Umgebungen auch namensräumlich organisiert sein, zum Beispiel staging/shop-de und production/shop-de.

Die url-Eigenschaft verlinkt die Umgebung mit der tatsächlichen URL des Shops. GitLab zeigt diese URL direkt in der Pipeline-Übersicht als klickbaren Link, was das Verifizieren nach einem Deployment beschleunigt. Der Wert kann statisch oder aus einer Variable zusammengesetzt sein, was für dynamische Umgebungen wie Review Apps nützlich ist.

# environments.yml — Environment definitions for a Magento project

# Staging: auto-deploy on merge to main
deploy:staging:
  stage: deploy
  environment:
    name: staging
    url: "https://staging.shop.example.com"
    on_stop: teardown:staging  # Optional: cleanup job
  script:
    - ./bin/deploy.sh staging
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
      when: on_success  # Automatic after successful test stage

# Production: manual trigger only, from tagged releases
deploy:production:
  stage: deploy
  environment:
    name: production
    url: "https://shop.example.com"
  script:
    - ./bin/deploy.sh production
  rules:
    - if: '$CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/'
      when: manual  # Requires human confirmation in GitLab UI
  allow_failure: false  # Pipeline stays pending until triggered

3. Staging: Automatisches Deployment nach Merge

Staging-Deployments sollten in den meisten Teams automatisch nach einem erfolgreichen Merge auf den Haupt-Branch ausgelöst werden. Das setzt voraus, dass die vorherigen Stages – Build, Test, Qualitätsprüfung – erfolgreich waren. Das automatische Staging-Deployment gibt dem Team kontinuierlich eine aktuelle Version zum Testen, ohne dass jemand manuell eingreifen muss. Gleichzeitig ist Staging die Grundlage dafür, dass Production-Freigaben auf einem bereits getesteten Stand basieren.

Eine wichtige Konfiguration für automatische Staging-Deployments ist die needs-Direktive, die sicherstellt, dass der Deploy-Job erst startet, wenn alle abhängigen Build- und Test-Jobs erfolgreich abgeschlossen haben. Ohne explizite Abhängigkeiten könnte ein Staging-Deployment theoretisch parallel zu noch laufenden Tests starten – je nach Pipeline-Konfiguration. Mit needs ist die Reihenfolge garantiert.

Für Magento-Projekte bedeutet ein automatisches Staging-Deployment typischerweise: Artefakte auf den Staging-Server übertragen, Symlinks setzen, Shared-Dateien verknüpfen, setup:upgrade ausführen (wenn Datenbankmigrationen vorhanden sind), Static Content deployen, Cache flushen und einen Smoke Test gegen die Staging-URL ausführen. Der gesamte Prozess dauert typischerweise 3–7 Minuten und gibt dem Team unmittelbares Feedback nach jedem Merge.

4. Production: Manuelles Deployment mit expliziter Freigabe

Production-Deployments erfordern eine bewusste Entscheidung. In GitLab wird das über when: manual im Deployment-Job implementiert. Der Job wird in der Pipeline angezeigt, ist aber paused und wartet auf eine manuelle Auslösung durch einen autorisierten Nutzer. allow_failure: false stellt sicher, dass die Pipeline-Status als "waiting" angezeigt wird, nicht als "failed" oder "success", was die Dringlichkeit des ausstehenden Freigabeschritts sichtbar macht.

Die Kombination aus manuellen Production-Jobs und Protected Branches stellt sicher, dass nur autorisierte Personen Production-Deployments auslösen können. Wenn der Production-Job auf einem protected Tag läuft (zum Beispiel v1.2.3), können nur Maintainer und Owners des Projekts den Job auslösen – normale Entwickler sehen den Button, können ihn aber nicht klicken. Diese Zugriffskontrolle ist eine technische Durchsetzung des Vier-Augen-Prinzips.

# Production deployment with manual gate and proper scoping

.deploy:base:
  script:
    - eval $(ssh-agent -s)
    - echo "${SSH_PRIVATE_KEY}" | ssh-add -
    - mkdir -p ~/.ssh && chmod 700 ~/.ssh
    - echo "${SSH_KNOWN_HOSTS}" >> ~/.ssh/known_hosts
    - rsync -az --delete \
        --exclude='.git' \
        --exclude='var/' \
        --exclude='pub/media/' \
        "./" "${DEPLOY_USER}@${DEPLOY_HOST}:${RELEASE_PATH}/"
    - ssh "${DEPLOY_USER}@${DEPLOY_HOST}" "bash -s" < ./bin/post-deploy.sh

deploy:staging:
  extends: .deploy:base
  stage: deploy
  environment:
    name: staging
    url: "https://staging.shop.example.com"
  variables:
    RELEASE_PATH: "${STAGING_DEPLOY_PATH}/releases/$(date +%Y%m%d-%H%M%S)"
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
      when: on_success

deploy:production:
  extends: .deploy:base
  stage: deploy
  environment:
    name: production
    url: "https://shop.example.com"
  variables:
    RELEASE_PATH: "${PROD_DEPLOY_PATH}/releases/${CI_COMMIT_TAG}"
  rules:
    - if: '$CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/'
      when: manual  # Explicit human approval required
  allow_failure: false

5. Environment-Approvals: Formelle Freigaben in GitLab Premium

GitLab Premium und Ultimate bieten Environment-Approvals als formalen Freigabeprozess. Wenn eine Umgebung mit einem Approval-Prozess konfiguriert ist, müssen bestimmte Personen oder Gruppen explizit ihre Zustimmung geben, bevor ein Deployment-Job in dieser Umgebung ausgeführt werden darf. Das unterscheidet sich von einem einfachen manuellen Job, weil die Freigabe als eigenes Ereignis in den Audit-Logs erscheint und nachvollziehbar dokumentiert ist.

Die Konfiguration von Environment-Approvals erfolgt in den GitLab-Projekteinstellungen unter CI/CD > Environments. Dort kann für jede Umgebung festgelegt werden, wie viele Approvals benötigt werden und welche Nutzer oder Gruppen als Approver konfiguriert sind. Diese Einstellung ist bewusst außerhalb der .gitlab-ci.yml gehalten, damit ein Entwickler sie nicht durch einen Commit in der Pipeline-Datei umgehen kann.

Für Teams ohne GitLab Premium gibt es eine pragmatische Alternative: Ein separater manueller Job approve:production vor dem eigentlichen Deploy-Job, der als Freigabe-Schritt dient. Dieser Job hat keine eigentliche Funktion außer dem Klick-Bestätigung, aber er erscheint in der Pipeline-History und macht sichtbar, wer und wann freigegeben hat. In Kombination mit dem Nutzer-Audit-Log in GitLab ergibt das eine vollständige Freigabedokumentation.

6. Deployment-History: Sichtbarkeit über alle Umgebungen

Die Deployment-History in GitLab ist eine der wertvollsten, aber am wenigsten bekannten Funktionen. Unter Operate > Environments zeigt GitLab für jede Umgebung eine chronologische Liste aller Deployments mit Zeitstempel, ausgelöstem Job, Commit-SHA, Branch/Tag-Name und dem GitLab-Nutzer, der den Deploy ausgelöst hat. Von dort aus kann direkt in einen Rollback-Job für einen bestimmten historischen Deploy gesprungen werden.

Für Magento-Teams ist die Deployment-History eine praktische Antwort auf die Frage "Was läuft gerade auf Production?". Statt SSH-Zugriff auf den Server zu benötigen oder Logdateien zu lesen, gibt die GitLab-Übersicht sofort die Information: Tag v1.2.3, deployed am 09.05.2026 um 14:33 Uhr, durch Nutzer admin@mironsoft.de. Das ist nicht nur für den laufenden Betrieb nützlich, sondern auch für Audit-Nachweise und Incident-Analysen.

# Rollback job tied to the environment for history integration

rollback:production:
  stage: rollback
  environment:
    name: production
    action: rollback  # Marks this as a rollback in the deployment history
  when: manual
  script:
    - ssh "${DEPLOY_USER}@${DEPLOY_HOST}" "bash -s" << 'ENDSSH'
      set -euo pipefail

      # List last 5 releases for operator reference
      echo "Available releases for rollback:"
      ls -lt "${PROD_DEPLOY_PATH}/releases/" | head -6 | tail -5

      # ROLLBACK_TO variable must be set in manual trigger
      TARGET="${PROD_DEPLOY_PATH}/releases/${ROLLBACK_TO:?Variable ROLLBACK_TO required}"
      test -d "${TARGET}" || { echo "ERROR: Release not found"; exit 1; }

      ln -sfn "${TARGET}" "${PROD_DEPLOY_PATH}/current"
      cd "${PROD_DEPLOY_PATH}/current"
      bin/magento cache:flush
      echo "Rolled back to ${TARGET}"
      ENDSSH
  variables:
    ROLLBACK_TO: ""  # Must be provided via manual trigger variables
  rules:
    - when: manual
      allow_failure: false

7. Variable-Scoping nach Environment

Variable-Scoping ist die technische Grundlage dafür, dass Staging- und Production-Deployments unterschiedliche Server, Pfade und Credentials verwenden, ohne dass diese Konfiguration in der Pipeline-Datei hardgecoded sein muss. In den GitLab-Projekteinstellungen kann jede Variable mit einem Environment-Scope versehen werden: staging oder production. Ein Job, der environment: name: staging deklariert, erhält ausschließlich die Staging-variablen; der Production-Job erhält ausschließlich die Production-Variablen.

Das Scoping funktioniert auch mit Wildcards: Ein Scope review/* gilt für alle Environments, deren Name mit review/ beginnt. Das ist besonders für Review Apps nützlich, die für jeden Feature-Branch eine eigene temporäre Umgebung erstellen. Variablen mit dem Scope * gelten für alle Environments und sind der Fallback, wenn kein spezifischerer Scope zutrifft.

Eine häufige Frage ist, ob Environment-Scoping auch für Secrets wie SSH-Schlüssel gilt. Die Antwort ist ja: Wenn SSH_PRIVATE_KEY für Staging und für Production als getrennte Variablen mit unterschiedlichem Scope konfiguriert sind, verwendet der Staging-Job den Staging-SSH-Schlüssel und der Production-Job den Production-SSH-Schlüssel. Es ist technisch nicht möglich, mit einem Staging-Job den Production-SSH-Schlüssel zu extrahieren, wenn das Scoping korrekt konfiguriert ist.

8. Vergleich: Deployment-Freigabemodelle

Für die Entscheidung, wie Production-Freigaben implementiert werden sollen, ist ein Vergleich der verfügbaren Modelle hilfreich. Jedes Modell hat andere Voraussetzungen und bietet unterschiedliche Grade an Formalisierung und Auditierbarkeit.

Modell Voraussetzung Auditierbarkeit Geeignet für
when: manual GitLab Free Basis (Nutzer + Zeitstempel) Kleine Teams, einfache Prozesse
Environment-Approvals GitLab Premium Vollständig (eigenes Audit-Event) Compliance, PCI-DSS, ISO 27001
Protected Tags + Manual GitLab Free Tag-Creation + Deploy-Event Release-basierte Workflows
Approve-Job + Deploy-Job GitLab Free Zwei separate Audit-Events PCI-Proxy ohne Premium-License
Vollautomatisch (CD) Reife Pipeline + Tests Pipeline-Log vollständig Reife CD-Prozesse, SaaS

Für Magento E-Commerce-Projekte mit regulierten Anforderungen ist die Kombination aus Protected Tags, manuellem Deploy-Job und – sofern verfügbar – Environment-Approvals die empfohlene Konfiguration. Sie bietet eine klare Freigabe-Semantik, ist auditierbar und macht für jeden Beteiligten sichtbar, welche Version auf Production läuft und wer sie freigegeben hat.

9. Typische Fehlerbilder bei Environments und Freigaben

Ein häufiges Fehlerbild ist ein fehlerhaft konfigurierter Variable-Scope, bei dem Staging-Variablen auf Production-Jobs wirken oder umgekehrt. Das passiert, wenn Variablen ohne Scope konfiguriert werden und für alle Environments gelten. In diesem Fall sind Staging und Production nicht isoliert – ein Sicherheitsrisiko und eine Quelle von Konfigurationsfehlern. Die Lösung ist konsequentes Scoping: Jede umgebungsspezifische Variable bekommt einen expliziten Environment-Scope.

Ein zweites Fehlerbild betrifft when: manual-Jobs ohne allow_failure: false. Wenn der manuelle Deployment-Job nicht ausgelöst wird, setzt GitLab ihn standardmäßig als "skipped" und markiert die gesamte Pipeline als "passed". Das bedeutet: Die Pipeline ist grün, obwohl kein Production-Deployment stattgefunden hat. Wer nicht explizit auf die Pipeline-Details schaut, übersieht möglicherweise den ausstehenden Deploy. Mit allow_failure: false bleibt die Pipeline im Status "waiting for manual action", was die Dringlichkeit besser kommuniziert.

Ein drittes Fehlerbild ist die fehlende Verknüpfung des Rollback-Jobs mit der Umgebung. Wenn der Rollback-Job kein environment mit action: rollback deklariert, erscheint er nicht in der Deployment-History der Umgebung. Das macht es schwieriger, nach einem Rollback zu nachzuvollziehen, was wann auf welchem Stand war. Jeder Job, der den Zustand einer Umgebung ändert – Deploy, Rollback oder Teardown – sollte die Umgebung korrekt referenzieren.

10. Zusammenfassung

GitLab Environments, Manual Jobs und Freigaben für Staging und Production bilden die Grundlage für einen nachvollziehbaren, kontrollierten Deployment-Prozess. Environments machen Deployments sichtbar und verknüpfen Variable-Scoping mit konkreten Zielumgebungen. Automatische Staging-Deployments geben dem Team kontinuierliches Feedback. Manuelle Production-Jobs erzwingen eine bewusste Freigabe durch autorisierten Personal. Environment-Approvals in GitLab Premium formalisieren diesen Prozess für Compliance-Anforderungen.

Das korrekte Zusammenspiel dieser Mechanismen – Environment-Deklaration, Variable-Scoping, Protected Tags und manuelle Freigaben – ist das Fundament dafür, dass Magento-Deployments nicht nur technisch funktionieren, sondern auch organisatorisch kontrolliert und auditierbar sind. Wer diese Konfiguration von Anfang an umsetzt, schafft einen Deployment-Prozess, der im Normalbetrieb effizient ist und im Störfall klare Aussagen über den aktuellen und historischen Systemzustand liefert.

GitLab Environments und Freigaben — Das Wichtigste auf einen Blick

Staging automatisch

when: on_success nach Merge auf main. needs-Abhängigkeiten für korrekte Reihenfolge. Vollautomatisch nach bestandenen Tests.

Production manuell

when: manual mit allow_failure: false. Nur auf Protected Tags. Nur Maintainer können auslösen. Klarer Freigabe-Zeitstempel im Audit-Log.

Variable-Scoping

Jede umgebungsspezifische Variable mit Environment-Scope konfigurieren. Staging und Production sind technisch isoliert.

Deployment-History

Operate > Environments zeigt chronologische Deploy-History. Rollback-Jobs mit action: rollback verknüpfen. Immer nachvollziehbar.

11. FAQ: GitLab Environments, Manual Jobs und Freigaben

1when: manual vs. Environment-Approvals?
when: manual ist ein Button-Klick für autorisierte Nutzer. Environment-Approvals (Premium) sind ein formaler Prozess mit eigenem Audit-Event.
2Entwickler von Production-Deploy fernhalten?
Protected Tags + when: manual. Nur Maintainer und Owners können auf Protected Tags manuelle Jobs auslösen.
3Was zeigt Operate > Environments?
Aktuell deployten Stand, letzten Deployment-Zeitstempel, auslösenden Nutzer und URL. Plus chronologische Deployment-History.
4Variable-Scoping isoliert Staging von Production?
Ja. Variables mit Scope 'staging' sind nur in Staging-Jobs verfügbar. Technische Isolation, nicht nur Konvention.
5Manueller Job nicht ausgelöst?
Ohne allow_failure: false gilt Job als skipped und Pipeline als passed. Mit allow_failure: false bleibt Pipeline in "waiting"-Status.
6Rollback in Deployment-History sichtbar?
Ja, durch action: rollback im environment-Block. GitLab markiert den Deploy als Rollback in der History.
7Umgebung mit mehreren Deployment-Zielen?
GitLab kennt ein Ziel pro Environment. Multi-Server-Logik wird im Job-Script implementiert. Separater Job pro konzeptionellem Ziel.
8Aktuelle Version auf Production sehen?
Operate > Environments > production. Commit-SHA, Tag, Zeitstempel, Nutzer und URL – ohne SSH-Zugriff.
9Job auf mehrere Environments deployen?
Ein Job – ein Environment. Für mehrere Umgebungen separate Jobs definieren: deploy:staging und deploy:production.
10Zugang zu Environment-Approvals konfigurieren?
In Settings > CI/CD > Environments. Approver-Gruppen, Nutzer und Anzahl benötigter Approvals. Nicht über .gitlab-ci.yml konfigurierbar.