Manuelles Testen und Deployen ist fehleranfällig, langsam und nervig. GitLab CI/CD automatisiert den gesamten Weg vom Commit bis zur Produktion: Bei jedem Push laufen automatisch Tests, Builds und – wenn alles grün ist – das Deployment. Das Schöne daran: Die gesamte Konfiguration steckt in einer einzigen Datei im Repository, versioniert und nachvollziehbar wie der Code selbst. Dieser Artikel führt dich von den Grundbegriffen bis zur ersten lauffähigen Pipeline.
Die Grundbegriffe von GitLab CI/CD
Bevor wir Konfiguration schreiben, klären wir die zentralen Begriffe:
- Pipeline: Der gesamte automatisierte Ablauf, der bei einem auslösenden Ereignis (z. B. Push, Merge Request) startet.
- Stage: Eine Phase der Pipeline, etwa
build,test,deploy. Stages laufen nacheinander. - Job: Eine konkrete Aufgabe innerhalb einer Stage, z. B. "Unit-Tests ausführen". Jobs derselben Stage laufen parallel.
- Runner: Der Agent, der die Jobs tatsächlich ausführt – auf einem Server, in einem Container oder in der Cloud.
Die komplette Konfiguration liegt in der Datei .gitlab-ci.yml im Wurzelverzeichnis deines Repositorys. GitLab erkennt sie automatisch und startet bei jedem Push die definierte Pipeline.
Die erste .gitlab-ci.yml
Eine minimale Pipeline definiert Stages und ordnet Jobs zu. Konzeptionell sieht das so aus: Du legst oben die Reihenfolge der Stages fest und definierst dann pro Job, in welche Stage er gehört und welche Befehle (das script) er ausführt.
Ein typisches Beispiel für eine Node-Anwendung umfasst drei Stages:
- build: Ein Job
build-job, dernpm ciundnpm run buildausführt und das Build-Ergebnis als Artefakt sichert. - test: Ein Job
test-job, der die Testsuite mitnpm testdurchlaufen lässt. - deploy: Ein Job
deploy-job, der nur auf dem Hauptbranch läuft und die Anwendung auf den Zielserver bringt.
Jeder Job gibt mit dem Schlüssel image an, in welchem Docker-Image er ausgeführt wird (etwa node:20-alpine). Das macht Builds reproduzierbar, weil jeder Job in einer sauberen, definierten Umgebung startet.
Runner: Wer führt die Jobs aus?
Ohne Runner passiert nichts. Auf gitlab.com stehen geteilte Runner (Shared Runners) bereit, sodass du sofort loslegen kannst – allerdings im Rahmen eines Minutenkontingents. Bei einer selbst gehosteten GitLab-Instanz oder für mehr Kontrolle registrierst du eigene Runner.
Am verbreitetsten ist der Docker-Executor: Jeder Job läuft in einem frischen Container des angegebenen Images. Das garantiert Isolation und Sauberkeit. Alternativen sind der Shell-Executor (Jobs laufen direkt auf dem Runner-Host) und der Kubernetes-Executor (Jobs als Pods im Cluster). Für die meisten Teams ist der Docker-Executor die richtige Wahl.
Caching und Artefakte richtig nutzen
Ein häufiger Anfängerfehler: In jedem Job werden Abhängigkeiten neu heruntergeladen, was die Pipeline unnötig verlangsamt. Hier helfen zwei Konzepte, die man nicht verwechseln sollte:
- Cache: Beschleunigt Pipelines, indem wiederverwendbare Daten (z. B.
node_modulesoder das.npm-Verzeichnis) zwischen Pipeline-Läufen erhalten bleiben. Der Cache ist eine Performance-Optimierung und darf verloren gehen. - Artefakt: Ein Ergebnis eines Jobs, das an nachfolgende Jobs weitergegeben oder zum Download bereitgestellt wird – etwa das fertige Build-Verzeichnis oder ein Test-Report. Artefakte sind verlässlich und werden für eine konfigurierbare Zeit aufbewahrt.
Faustregel: Den Cache nutzt du für Abhängigkeiten, die du nicht im Repo hast, aber regenerieren könntest. Artefakte nutzt du, um Build-Ergebnisse von einer Stage zur nächsten zu reichen.
Pipeline gezielt steuern mit Rules
Selten soll jeder Job bei jedem Anlass laufen. Das Deployment in die Produktion etwa sollte nur vom Hauptbranch erfolgen, nicht von jedem Feature-Branch. Dafür gibt es das Schlüsselwort rules (das ältere only/except gilt als veraltet). Mit rules definierst du Bedingungen, etwa:
- Den Deploy-Job nur ausführen, wenn der Branch
mainist. - Bestimmte Jobs nur bei Merge Requests laufen lassen.
- Ein Deployment in Produktion als
manualmarkieren, sodass es erst nach einem bewussten Klick im GitLab-UI startet (ein manuelles Freigabe-Gate).
Gerade das manuelle Gate für Produktions-Deployments ist eine bewährte Sicherheitsmaßnahme: Tests und Staging-Deployment laufen automatisch, aber der finale Schritt in die Produktion bleibt in menschlicher Hand.
Secrets und Variablen sicher verwalten
Niemals gehören Passwörter, API-Tokens oder SSH-Schlüssel im Klartext in die .gitlab-ci.yml. Stattdessen hinterlegst du sie als CI/CD-Variablen in den Projekteinstellungen (Settings → CI/CD → Variables). Dort lassen sie sich als "protected" (nur für geschützte Branches) und "masked" (im Job-Log unkenntlich gemacht) markieren.
Für besonders sensible Umgebungen unterstützt GitLab auch die Integration externer Secret-Manager wie HashiCorp Vault. Wenn du sichere Tokens oder zufällige Geheimnisse für deine Variablen brauchst, hilft dir unser Passwort-Generator beim Erzeugen kryptografisch starker Werte. Weitere praktische Helfer für den Entwickleralltag findest du im Webtools-Bereich.
Vom Build zum Deployment
Wie das eigentliche Deployment aussieht, hängt von deinem Ziel ab. Verbreitete Muster sind:
- Container-Image bauen und pushen: Im Build-Job ein Docker-Image erstellen und in die GitLab Container Registry oder eine andere Registry pushen.
- Deployment per SSH: Über einen hinterlegten SSH-Key auf den Zielserver verbinden und dort das neue Image ziehen und starten.
- Kubernetes-Deployment: Mit
kubectloder Helm das aktualisierte Manifest auf den Cluster anwenden. - PaaS-Integration: Über ein CLI-Tool des Anbieters direkt deployen.
GitLab bietet zudem das Konzept der Environments, mit dem du Deployments nach Umgebung (Staging, Production) gruppierst und im UI nachverfolgst, welche Version gerade wo läuft – inklusive Rollback-Möglichkeit auf eine vorherige Version.
Best Practices für robuste Pipelines
- Fail fast: Lege schnelle Checks (Linting, Unit-Tests) in frühe Stages, damit Fehler sofort auffallen und die Pipeline früh abbricht.
- Pipelines schlank halten: Nutze Caching konsequent und vermeide unnötige Schritte. Lange Pipelines bremsen das ganze Team aus.
- Reproduzierbarkeit: Pinne Image-Versionen exakt (
node:20.11-alpinestattnode:latest), damit Builds heute wie in einem Jahr identisch laufen. - DRY mit Templates: Wiederkehrende Job-Definitionen lassen sich mit
extendsund versteckten Jobs (mit führendem Punkt) auslagern und wiederverwenden. - Aussagekräftige Logs: Sorge dafür, dass fehlgeschlagene Jobs klar sagen, was schiefging – das spart später viel Sucherei.
Häufige Fragen
Was ist der Unterschied zwischen CI und CD?
Continuous Integration (CI) meint das automatische Bauen und Testen bei jeder Änderung, damit Integrationsprobleme früh auffallen. Continuous Delivery/Deployment (CD) erweitert das um die automatisierte Auslieferung – bei Delivery bis zu einem freigabebereiten Stand, bei Deployment vollautomatisch bis in die Produktion.
Ist GitLab CI/CD kostenlos?
Die CI/CD-Funktion selbst ist Teil von GitLab, auch in der Free-Stufe. Auf gitlab.com gibt es ein monatliches Kontingent an Runner-Minuten in der kostenlosen Variante; darüber hinaus oder mit eigenen Runnern fallen entsprechende Kosten an. Eine selbst gehostete GitLab-Instanz mit eigenen Runnern verursacht nur deine Infrastrukturkosten.
Wie unterscheidet sich GitLab CI/CD von GitHub Actions?
Beide lösen dasselbe Problem mit ähnlichen Konzepten. GitLab CI/CD ist eng in die GitLab-Plattform integriert und nutzt eine einzelne .gitlab-ci.yml. GitHub Actions setzt stärker auf einen Marktplatz wiederverwendbarer Actions. Welches besser passt, hängt vor allem davon ab, welche Plattform du ohnehin nutzt.
Warum schlägt meine Pipeline fehl, obwohl der Code lokal funktioniert?
Meist liegt es an Umgebungsunterschieden: andere Abhängigkeitsversionen, fehlende Umgebungsvariablen oder Annahmen über lokal vorhandene Dateien. Genau deshalb laufen Jobs in sauberen Containern – das deckt versteckte Abhängigkeiten von deinem lokalen Setup auf. Prüfe das Job-Log genau, oft steht die Ursache direkt darin.