CI/CD
.yml
GitLab · CI/CD · Magento · Repository-Governance
GitLab Grundlagen für Deployment-Serien
Projekte, Gruppen, Rollen, Protected Branches

Ohne klare Repository-Governance sind selbst gut geschriebene Pipelines organisatorisch fragil. Projekte, Gruppen, Zugriffsrollen und Protected Branches bilden das Fundament, auf dem sichere Magento-Deployment-Serien aufgebaut werden können.

15 Min. Lesezeit Projekte · Gruppen · Rollen · Protected Branches · CI/CD-Variablen GitLab 16+ · Magento 2.4 · PHP 8.4

1. Warum Repository-Governance vor der Pipeline kommt

Eine GitLab CI/CD-Pipeline ist nur so verlässlich wie die organisatorischen Regeln, die sie umgeben. Wer direkt mit der .gitlab-ci.yml beginnt, ohne vorher zu klären, wer welchen Branch pushen darf, welche Variablen in welcher Umgebung gelten und wie Freigaben für Production gesteuert werden, baut auf instabilem Boden. Die GitLab Grundlagen für Deployment-Serien beginnen deshalb nicht mit Syntax, sondern mit Strukturentscheidungen: Projekte, Gruppen, Rollen und Branch-Schutz sind die Grundlage, auf der reproduzierbare Deployments entstehen.

Gerade bei Magento-Projekten ist dieser Punkt besonders relevant. Ein Magento-Shop besteht aus mehreren Schichten – Custom-Module, Theme, Composer-Abhängigkeiten, Konfigurationsdateien und Umgebungsvariablen – die alle in der Pipeline korrekt verwaltet werden müssen. Wenn jeder Entwickler direkt auf main pushen kann und Production-Variablen für alle sichtbar sind, ist ein stabiler Deployment-Prozess kaum erreichbar. Die Governance-Entscheidungen zu Beginn eines Projekts bestimmen, wie viel manuelle Aufsicht später noch notwendig ist.

Die folgenden Abschnitte behandeln die wichtigsten GitLab-Grundkonzepte im Kontext von Magento-Deployment-Serien: angefangen bei der Projektstruktur über Gruppen und Rollen bis zu Protected Branches und CI/CD-Variablen mit Environment-Scope. Wer diese Bausteine kennt und bewusst einsetzt, schafft die Voraussetzung dafür, dass auch komplexe Deployment-Pipelines langfristig wartbar und sicher bleiben.

2. GitLab-Projekte richtig strukturieren

Ein GitLab-Projekt ist mehr als ein Git-Repository. Es ist der Container für Code, Pipeline-Konfiguration, CI/CD-Variablen, Environments, Deploy Keys und Zugriffsregeln. Bei Magento-Projekten empfiehlt es sich, den gesamten Shop-Code – also Custom-Module, Theme, Composer-Abhängigkeiten und Konfigurationsdateien – in einem einzigen Monorepo zu verwalten. Das vereinfacht die Pipeline-Logik erheblich: Ein Build-Trigger, ein Artefakt, ein Deploy-Job. Separate Repositories für Theme und Module erhöhen die Komplexität und erfordern zusätzliche Koordination zwischen Pipelines.

Die Projekteinstellungen in GitLab unter Settings > General enthalten wichtige Deployment-relevante Optionen: Visibility sollte für produktive Repositories auf Private gesetzt sein. Merge Requests sollte aktiviert sein, damit kein Code ohne Review in Protected Branches gelangen kann. Die Option Delete source branch after merge hält den Branch-Baum übersichtlich. Unter Settings > Repository wird der Default Branch festgelegt – für Magento-Projekte ist main der Standard.

# .gitlab-ci.yml — Project-level pipeline configuration
# Default branch: main | Protected branches: main, release/*
# All secrets managed via Settings > CI/CD > Variables with environment scope

default:
  tags:
    - magento-runner       # Restrict jobs to dedicated runner
  retry:
    max: 1
    when: runner_system_failure

workflow:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    - if: '$CI_COMMIT_BRANCH == "main"'
    - if: '$CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/'

3. Gruppen und Untergruppen für Magento-Teams

GitLab-Gruppen ermöglichen es, mehrere Projekte unter einer gemeinsamen Namespace-Ebene zu verwalten und Zugriffsrechte, Runner und CI/CD-Variablen auf Gruppenebene zu definieren. Für Agenturen oder Teams, die mehrere Magento-Shops betreuen, ist eine sinnvolle Gruppenstruktur essenziell. Eine typische Struktur könnte mironsoft/ als Hauptgruppe mit Untergruppen pro Kunde enthalten – etwa mironsoft/kunde-a/shop und mironsoft/kunde-b/shop. Auf Gruppenebene definierte Variablen gelten automatisch für alle Projekte in der Gruppe, was die Verwaltung von gemeinsamen Secrets wie COMPOSER_AUTH erheblich vereinfacht.

Gruppen-Runner, die auf Gruppenebene registriert sind, stehen allen Projekten der Gruppe zur Verfügung. Das ist besonders praktisch, wenn mehrere Magento-Shops denselben Build-Runner nutzen sollen, ohne dass jedes Projekt einen eigenen Runner konfigurieren muss. Untergruppen erlauben dabei feingranulare Trennung: Ein Runner für Test-Umgebungen kann auf Untergruppen-Ebene eingeschränkt werden, ohne die Production-Runner zu berühren.

4. Zugriffsrollen und Berechtigungen verstehen

GitLab kennt fünf Rollen: Guest, Reporter, Developer, Maintainer und Owner. Für Deployment-Serien sind vor allem die Unterschiede zwischen Developer und Maintainer relevant. Developers dürfen Branches pushen, Merge Requests erstellen und Pipelines ausführen – aber keine Protected Branches direkt pushen und keine CI/CD-Variablen verwalten. Maintainer dürfen zusätzlich Protected Branches und Tags konfigurieren, Runner registrieren und Projekt-Settings ändern. Im Magento-Kontext sollten Entwickler in der Regel als Developer eingetragen sein, während der DevOps-Verantwortliche Maintainer-Rechte erhält.

Deploy Keys sind eine weitere wichtige Berechtigungsebene: Sie erlauben Read-only oder Read-Write-Zugriff auf ein Repository für externe Systeme, ohne dass ein persönlicher Access Token mit vollen Benutzerrechten verwendet werden muss. Für Deployment-Skripte, die auf den Server zugreifen, ist ein separater Deploy Key mit Read-only-Zugriff die sichere Wahl. Kombiniert mit SSH-Keys für den Deployment-User auf dem Zielserver entsteht ein Zugriffsmodell ohne unnötig breite Berechtigungen.

# Role-based pipeline restrictions
# Only Maintainers can trigger production deployments via protected tags

deploy:production:
  stage: deploy
  environment:
    name: production
    url: https://shop.mironsoft.de
  rules:
    # Trigger only on protected version tags (pushed by Maintainer)
    - if: '$CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/'
      when: manual
  script:
    - echo "Deploying release $CI_COMMIT_TAG to production"
    - bash deploy/deploy.sh
  allow_failure: false

5. Protected Branches als Deployment-Schranke

Protected Branches sind das zentrale Governance-Werkzeug in GitLab. Sie definieren, wer direkt auf einen Branch pushen darf, wer Merge Requests zusammenführen darf und ob Force Pushes erlaubt sind. Für Magento-Deployment-Serien ist die Konfiguration klar: main wird als Protected Branch eingerichtet mit der Einstellung Allowed to push: No one und Allowed to merge: Maintainers. Das bedeutet, dass kein Entwickler direkt auf main pushen kann – alle Änderungen müssen über einen Merge Request mit Review laufen.

Zusätzlich zu main sollten auch Release-Branches wie release/* als Protected Branches konfiguriert werden. Diese Branches werden für Hotfix-Workflows und Release-Kandidaten verwendet und dürfen ebenfalls nur von Maintainern zusammengeführt werden. Die Option Code owner approval – verfügbar in GitLab Premium – ermöglicht es, für bestimmte Verzeichnisse wie app/etc/ oder .gitlab-ci.yml einen verpflichtenden Review durch den zuständigen Code-Owner zu erzwingen. Das ist besonders für sicherheitskritische Konfigurationsdateien sinnvoll.

6. Protected Tags für Release-Freigaben

Während Protected Branches den Workflow für laufende Entwicklung absichern, steuern Protected Tags den Moment der Release-Freigabe. Das Muster für Magento-Deployments: Ein Production-Deploy wird nur ausgelöst, wenn ein Tag nach dem Muster v* erstellt wird – und Tags dürfen nur von Maintainern erstellt werden. Das erzeugt eine natürliche Freigabeschranke, die verhindert, dass unbeabsichtigt Code in Production gelangt.

Protected Tags sind unter Settings > Repository > Protected tags konfiguriert. Das Pattern v* schützt alle Tags, die mit v beginnen, also v1.2.3, v2.0.0-rc1 und so weiter. Nur Rollen mit Maintainer-Berechtigung oder höher können solche Tags erstellen. In der .gitlab-ci.yml kann ein Deploy-Job dann über die Regel if: '$CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/' exklusiv für diese Tags konfiguriert werden. Das verbindet Repository-Governance direkt mit der Pipeline-Logik.

# Protected tag pattern in .gitlab-ci.yml
# Only runs when a Maintainer creates a semantic version tag

stages:
  - build
  - test
  - package
  - deploy
  - verify
  - rollback

variables:
  GIT_STRATEGY: fetch
  COMPOSER_CACHE_DIR: .cache/composer
  NPM_CONFIG_CACHE: .cache/npm
  RELEASE_RETENTION: "5"

# Shared build configuration — reused across deploy jobs
.deploy_base:
  image: alpine:3.19
  before_script:
    - apk add --no-cache openssh-client rsync
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
    - mkdir -p ~/.ssh && chmod 700 ~/.ssh
    - echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts

7. CI/CD-Variablen mit Environment-Scope

CI/CD-Variablen in GitLab sind der Konfigurationsvertrag der Pipeline. Sie können auf Projektebene, Gruppenebene oder Instanzebene definiert werden und mit einem Environment-Scope versehen werden, der bestimmt, in welcher Umgebung eine Variable aktiv ist. Für Magento-Deployments bedeutet das: DEPLOY_HOST für die Staging-Umgebung hat einen anderen Wert als DEPLOY_HOST für Production – beide Variablen tragen denselben Namen, sind aber über den Environment-Scope getrennt. GitLab wählt automatisch die korrekte Variable basierend auf dem Environment-Namen des aktuellen Jobs.

Sensitive Variablen wie SSH_PRIVATE_KEY, COMPOSER_AUTH und Datenbank-Passwörter sollten als Masked markiert werden, damit sie in Job-Logs nicht im Klartext erscheinen. Die Option Protected stellt sicher, dass eine Variable nur in Jobs auf Protected Branches oder Protected Tags verfügbar ist – ein kritischer Sicherheitsmechanismus, der verhindert, dass Production-Secrets in Feature-Branch-Pipelines sichtbar werden. Diese Kombination aus Masking und Protected-Flag ist für alle Magento-Produktionsgeheimnisse Pflicht.

# Environment-scoped variable usage in deploy jobs
# Variables SSH_PRIVATE_KEY, DEPLOY_HOST, DEPLOY_PATH are scoped per environment

deploy:staging:
  extends: .deploy_base
  stage: deploy
  environment:
    name: staging
    url: https://staging.mironsoft.de
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
      when: on_success
  script:
    - |
      RELEASE_ID="$(date +%Y%m%d-%H%M%S)"
      RELEASE_PATH="${DEPLOY_PATH}/releases/${RELEASE_ID}"
      ssh "${DEPLOY_USER}@${DEPLOY_HOST}" "mkdir -p ${RELEASE_PATH}"
      rsync -az --delete --exclude='.git' ./ "${DEPLOY_USER}@${DEPLOY_HOST}:${RELEASE_PATH}/"
      ssh "${DEPLOY_USER}@${DEPLOY_HOST}" "
        ln -sfn ${DEPLOY_PATH}/shared/app/etc/env.php ${RELEASE_PATH}/app/etc/env.php
        ln -sfn ${RELEASE_PATH} ${DEPLOY_PATH}/current
        cd ${DEPLOY_PATH}/current && bin/magento cache:flush
      "
      echo "RELEASE_ID=${RELEASE_ID}" >> deploy.env
  artifacts:
    reports:
      dotenv: deploy.env

8. Governance-Muster im Vergleich

Die Entscheidung, wie viel Repository-Governance ein Projekt benötigt, hängt von der Teamgröße, dem Risikoprofil und der Anzahl der Umgebungen ab. Für ein Einzelentwickler-Projekt kann eine einfachere Struktur ausreichen, während Teamprojekte mit mehreren Entwicklern und einer Production-Umgebung von vollständiger Governance profitieren.

Governance-Aspekt Minimale Konfiguration Empfohlene Konfiguration Nutzen
Default Branch master (GitLab-Standard) main, explizit gesetzt Konsistenz mit CI/CD-Regeln
Branch-Schutz Kein Schutz main + release/* Protected Kein direkter Push auf kritische Branches
Tag-Schutz Alle Tags erlaubt v* nur für Maintainer Release-Freigabe kontrolliert
CI/CD-Variablen Global, keine Scopes Protected + Masked + Scoped Secrets nur in richtiger Umgebung
Merge Requests Optional, kein Review Pflicht mit Approval-Rule Vier-Augen-Prinzip vor Merge

In der Praxis zeigt sich: Teams, die Governance-Regeln erst nach dem ersten Produktionsvorfall einführen, zahlen einen höheren Preis als Teams, die von Anfang an klare Strukturen etablieren. Die Einrichtung von Protected Branches, Tag-Schutz und Environment-Scoped Variables dauert etwa eine Stunde – und spart erfahrungsgemäß viele Stunden an Incident-Management und manuellem Nacharbeiten.

9. Zusammenfassung

Die GitLab Grundlagen für Deployment-Serien – Projekte, Gruppen, Rollen und Protected Branches – sind kein bürokratischer Overhead, sondern die strukturelle Grundlage für alle weiteren Pipeline-Entscheidungen. Wer diese Bausteine bewusst konfiguriert, schafft einen Rahmen, in dem Entwickler sicher arbeiten können, ohne versehentlich kritische Branches oder Production-Environments zu berühren. Protected Branches verhindern direktes Pushen auf main. Protected Tags steuern, wer Releases auslösen darf. Environment-Scoped Variables trennen Staging- und Production-Geheimnisse sauber voneinander.

Für Magento-Projekte ist diese Struktur besonders wichtig, weil ein fehlerhafter Deploy direkt Umsatzverluste verursachen kann. Der Aufwand für die initiale Konfiguration ist überschaubar und die Entscheidungen, die dabei getroffen werden, sind nicht schwer – aber sie müssen bewusst und vollständig getroffen werden. Ein Deployment-Prozess, der diese Grundlagen nicht berücksichtigt, funktioniert möglicherweise in der Testphase, bricht aber unter realen Bedingungen mit mehreren Entwicklern und echten Release-Zyklen schnell zusammen.

GitLab Grundlagen — Das Wichtigste auf einen Blick

Repository-Governance

Protected Branches für main und release/* – kein direkter Push, alle Änderungen über Merge Requests mit Review.

Zugriffsrollen

Entwickler als Developer, DevOps-Verantwortliche als Maintainer. Nur Maintainer dürfen Protected Tags erstellen und Deployments auslösen.

CI/CD-Variablen

Alle Secrets als Protected + Masked + Environment-Scoped. Staging und Production erhalten eigene Werte für denselben Variablennamen.

Release-Freigabe

Production-Deploy nur über Protected Tags mit Muster v*. Kein automatisches Deployment ohne explizite Freigabe durch Maintainer.

10. Checkliste: Projekt-Setup für die erste Pipeline

Bevor die erste Pipeline für ein Magento-Projekt aktiviert wird, sollten alle Governance-Einstellungen korrekt konfiguriert sein. Die folgende Checkliste fasst die wichtigsten Punkte zusammen und stellt sicher, dass das Projekt-Setup den Anforderungen für sichere Deployment-Serien entspricht.

# Project setup checklist — verify before first pipeline run
# Settings > General
# - Visibility: Private
# - Merge Requests: Enabled
# - Squash commits: Optional
# - Delete branch after merge: Enabled

# Settings > Repository > Protected Branches
# - main: Allowed to push = No one, Allowed to merge = Maintainers
# - release/*: Allowed to push = No one, Allowed to merge = Maintainers

# Settings > Repository > Protected Tags
# - v*: Allowed to create = Maintainers

# Settings > CI/CD > Variables
# - SSH_PRIVATE_KEY: Protected, Masked, Scope = production/*
# - SSH_KNOWN_HOSTS: Protected, Scope = production/*
# - DEPLOY_HOST: Protected, Scope = production (different value per env)
# - DEPLOY_USER: Protected, Scope = *
# - DEPLOY_PATH: Protected, Scope = * (different value per env)
# - COMPOSER_AUTH: Protected, Masked, Scope = *
# - RELEASE_RETENTION: Not protected, Scope = *, Value = 5

Diese Checkliste ist der Ausgangspunkt für jede Deployment-Serie. Wer sie einmal sorgfältig durchgeht und alle Punkte korrekt konfiguriert, schafft eine solide Grundlage, auf der alle weiteren Pipeline-Jobs – Build, Test, Deploy, Verify und Rollback – sicher und reproduzierbar aufgebaut werden können. Die technische Pipeline ist nur so gut wie die organisatorischen Regeln, die sie umgeben.

11. FAQ: GitLab Grundlagen für Deployment-Serien

1Unterschied Projekt vs. Gruppe?
Projekt = einzelner Codebase mit Pipeline und Variablen. Gruppe = Namespace für mehrere Projekte mit geteilten Runnern, Variablen und Zugriffsrechten.
2Warum main als Protected Branch?
Verhindert direktes Pushen. Alle Änderungen über Merge Requests mit Review – schützt vor unbeabsichtigten Deployments und fehlerhafte Code-Stände in der Hauptlinie.
3Wie funktionieren Environment-Scoped Variables?
Gleicher Variablenname, unterschiedliche Werte pro Environment. GitLab wählt automatisch den passenden Wert basierend auf dem environment-Namen des Jobs.
4Masked vs. Protected Variables?
Masked: in Job-Logs nicht sichtbar. Protected: nur auf Protected Branches/Tags verfügbar. Für Production-Secrets beide Optionen kombinieren.
5Wann brauche ich eigenen Runner?
Bei SSH-Zugriff auf eigene Server, spezifischen Build-Tools oder Sicherheitsanforderungen. Shared Runner reichen nicht für Production-Deployments auf eigene Infrastruktur.
6Staging-Secrets von Production trennen?
Environment-Scoping + Protected-Flag. Staging-Variable mit Scope staging, Production-Variable mit Scope production – GitLab trennt automatisch.
7Was sind Deploy Keys?
SSH-Keys für Read-only oder Read-Write-Zugriff auf ein spezifisches Repository. Sicherer als persönliche Access Tokens für externe Systeme und CI-Runner.
8Protected Tags für Release-Steuerung?
Ja. Muster v* schützt Release-Tags – nur Maintainer können sie erstellen. Pipeline-Jobs mit if-Regel auf Tag-Muster laufen dann nur bei echten Releases.
9Monorepo oder mehrere Repositories?
Für Magento fast immer Monorepo: ein Build, ein Artefakt, eine Pipeline. Mehrere Repositories erhöhen Komplexität ohne proportionalen Nutzen.
10Was passiert ohne Branch-Schutz?
Jeder Entwickler kann direkt auf main pushen – keine technische Schranke vor fehlerhaften Production-Deployments. Governance muss von Anfang an konfiguriert werden.