GitLab Scheduled Pipelines: Naechtliche Builds, Security-Scans und Wartungsjobs automatisieren
AI generated
CI/CD
.yml
GitLab · CI/CD · Automatisierung
GitLab Scheduled Pipelines: Naechtliche Builds und Wartung automatisieren
cron-Syntax, Variablen und der Unterschied zum Server-Cronjob

Nicht jede Pipeline muss durch einen Push oder Merge Request ausgeloest werden. Naechtliche Security-Scans, wiederkehrende Aufraeumjobs oder regelmaessige Abhaengigkeits-Updates laufen am besten zeitgesteuert, unabhaengig davon, ob an dem Tag ueberhaupt jemand Code committet hat. GitLabs Scheduled Pipelines bieten dafuer einen in die Plattform integrierten Cron-Mechanismus. Dieser Artikel zeigt die Einrichtung, die cron-Syntax, den Umgang mit Pipeline-Variablen und warum eine Scheduled Pipeline etwas grundlegend anderes ist als ein klassischer Cronjob auf einem Server.

15 Min. Lesezeit Scheduled Pipelines cron-Syntax Wartungsjobs Automatisierung

1. Wozu zeitgesteuerte Pipelines gut sind

Die klassischen Pipeline-Trigger in GitLab, also Push, Merge Request und manuelle Ausloesung, decken den Alltag der Softwareentwicklung gut ab, lassen aber eine wichtige Kategorie von Aufgaben aussen vor: alles, was regelmaessig und unabhaengig von Code-Aenderungen passieren muss. Ein nächtlicher Security-Scan soll auch dann laufen, wenn tagsueber niemand committet hat. Ein woechentliches Dependency-Update soll pruefen, ob neue Versionen verfuegbar sind, ganz ohne dass jemand die Pipeline manuell startet.

Genau fuer diese Faelle gibt es Scheduled Pipelines. Sie werden im Projekt unter CI/CD > Schedules konfiguriert und ausgeloest GitLab die hinterlegte .gitlab-ci.yml so, als waere ein Pipeline-Trigger von aussen eingetroffen, allerdings mit CI_PIPELINE_SOURCE gleich schedule statt push. Damit lassen sich in derselben Pipeline-Datei sowohl normale Commit-Pipelines als auch die zeitgesteuerten Laeufe unterscheiden und mit unterschiedlichem Job-Umfang versehen, ohne zwei getrennte Pipelines pflegen zu muessen.

2. Einrichtung: Ein Schedule in der GitLab-Oberflaeche anlegen

Ein neuer Schedule wird unter Build > Pipeline schedules angelegt und besteht im Kern aus vier Angaben: einer Beschreibung, dem cron-Ausdruck fuer den Zeitpunkt, der Zeitzone sowie dem Ziel-Branch oder -Tag, auf dem die Pipeline ausgefuehrt wird. Zusaetzlich koennen pro Schedule eigene CI/CD-Variablen hinterlegt werden, die nur bei diesem konkreten Schedule gesetzt sind und in keiner anderen Pipeline auftauchen. Wichtig ist, dass der ausfuehrende Nutzer, unter dessen Identitaet die Pipeline laeuft, ausreichende Berechtigungen fuer alle referenzierten Jobs haben muss.

Nach dem Anlegen laesst sich der Schedule jederzeit ueber den Button Run now manuell ausloesen, was fuer das Testen der Konfiguration unverzichtbar ist. Erst wenn ein manueller Testlauf erfolgreich durchlaeuft, sollte man sich darauf verlassen, dass der cron-Ausdruck wie erwartet zuenden wird. GitLab fuehrt Scheduled Pipelines mit einer gewissen, technisch bedingten Verzoegerung von bis zu wenigen Minuten aus, was bei zeitkritischen Anwendungsfaellen einkalkuliert werden sollte.


# .gitlab-ci.yml
nightly-security-scan:
  stage: test
  script:
    - echo "Running nightly security scan"
  rules:
    - if: '$CI_PIPELINE_SOURCE == "schedule"'

3. Die cron-Syntax im Detail und die Rolle der Zeitzone

GitLab nutzt fuer Schedules die klassische Fuenf-Felder-cron-Syntax: Minute, Stunde, Tag des Monats, Monat und Wochentag, jeweils getrennt durch ein Leerzeichen. Der Ausdruck 0 2 * * * bedeutet demnach jeden Tag um zwei Uhr nachts, waehrend 0 3 * * 1-5 nur an Werktagen um drei Uhr feuert. Sternchen stehen fuer jeden moeglichen Wert des jeweiligen Feldes, Kommas trennen mehrere konkrete Werte und Bindestriche definieren Bereiche wie 1-5 fuer Montag bis Freitag.

Ein haeufig uebersehener Punkt ist die Zeitzone: Sie wird beim Anlegen des Schedules separat ausgewaehlt und ist unabhaengig von der Zeitzone des GitLab-Servers oder der Runner. Wer versaeumt, sie explizit auf die eigene Zielzeitzone zu setzen, wundert sich mitunter, warum der nächtliche Lauf mitten am Tag oder mehrere Stunden verschoben stattfindet, insbesondere bei GitLab.com, wo standardmaessig UTC verwendet wird. Bei der Umstellung von Sommer- auf Winterzeit kann sich der tatsaechliche Ausfuehrungszeitpunkt zudem um eine Stunde verschieben, was bei besonders zeitkritischen Jobs beruecksichtigt werden sollte.

4. Pipeline-Schedule-Variablen fuer unterschiedliche Laeufe nutzen

Jeder Schedule kann eigene CI/CD-Variablen mitbringen, die nur waehrend dieses spezifischen zeitgesteuerten Laufs gesetzt sind. Das erlaubt es, denselben Job in der .gitlab-ci.yml fuer unterschiedliche Zwecke wiederzuverwenden, etwa einen generischen Scan-Job, der je nach Schedule entweder einen schnellen taeglichen oder einen umfassenden woechentlichen Scan durchfuehrt, gesteuert ueber eine Variable wie SCAN_DEPTH. So muessen keine separaten Job-Definitionen fuer jede zeitliche Variante gepflegt werden.

In der Praxis bewaehrt es sich, mehrere Schedules mit klar sprechenden Beschreibungen anzulegen, zum Beispiel Nightly Quick Scan und Weekly Deep Scan, statt einen einzigen Schedule mit komplexer interner Verzweigungslogik zu ueberladen. Das macht die Konfiguration in der GitLab-Oberflaeche selbsterklaerend und erleichtert es neuen Teammitgliedern, auf einen Blick zu verstehen, welcher Schedule wofuer zustaendig ist, ohne die Pipeline-Definition im Detail lesen zu muessen.


# .gitlab-ci.yml
dependency-scan:
  stage: test
  variables:
    SCAN_DEPTH: "quick"
  script:
    - echo "Running dependency scan with depth $SCAN_DEPTH"
  rules:
    - if: '$CI_PIPELINE_SOURCE == "schedule"'

5. Scheduled Jobs mit rules gezielt von normalen Pipelines abgrenzen

Der Schluessel zur Unterscheidung zwischen einer normalen Commit-Pipeline und einem zeitgesteuerten Lauf ist die vordefinierte Variable CI_PIPELINE_SOURCE. Sie nimmt bei Scheduled Pipelines den Wert schedule an, waehrend sie bei einem gewoehnlichen Push push und bei einem Merge Request merge_request_event enthaelt. Mit einer rules-Bedingung wie if: $CI_PIPELINE_SOURCE == schedule laesst sich ein Job gezielt nur bei zeitgesteuerten Laeufen aktivieren oder umgekehrt bei normalen Commit-Pipelines gezielt deaktivieren.

Besonders nuetzlich ist die Kombination mehrerer rules-Bedingungen, um zwischen unterschiedlichen Trigger-Arten fein zu differenzieren: Ein umfangreicher, mehrere Minuten dauernder Integrationstest laeuft dann etwa nur bei Scheduled Pipelines, waehrend bei jedem normalen Push lediglich ein schneller Unit-Test-Lauf stattfindet. Das haelt die Feedback-Zeit fuer Entwickler kurz, ohne auf die gruendlichere, aber zeitaufwendigere Pruefung zu verzichten, die dann eben nachts automatisch erfolgt.

6. Warum eine Scheduled Pipeline kein klassischer Server-Cronjob ist

Auf den ersten Blick wirkt eine Scheduled Pipeline wie ein simpler Ersatz fuer einen crontab-Eintrag auf einem Server, doch die Unterschiede sind erheblich. Ein klassischer Cronjob laeuft direkt auf dem Zielserver, mit dessen lokaler Umgebung, dessen installierten Paketen und dessen Dateisystem, ganz ohne Containerisierung oder Isolation. Eine Scheduled Pipeline dagegen startet einen vollstaendigen GitLab-Runner-Job, typischerweise in einem frischen Docker-Container, inklusive Checkout des Repositories, Cache-Wiederherstellung und allem, was auch eine normale Pipeline mitbringt.

Das hat handfeste praktische Konsequenzen: Eine Scheduled Pipeline hat automatisch Zugriff auf Pipeline-Logs, Artifacts, den vollstaendigen Job-Verlauf in der GitLab-Oberflaeche und kann bei Fehlschlag ueber die gleichen Benachrichtigungsmechanismen wie jede andere Pipeline alarmieren, etwa per E-Mail oder Slack-Integration. Ein klassischer Server-Cronjob dagegen protokolliert bestenfalls in eine Logdatei oder per Mail an root, ohne die strukturierte Nachvollziehbarkeit, die GitLabs Pipeline-Historie von Haus aus mitbringt. Dafuer eignet sich ein echter Cronjob besser fuer Aufgaben, die direkt und ohne Container-Overhead auf dem Zielsystem selbst laufen muessen, etwa eine Datenbank-Wartung auf demselben Host.

7. Anwendungsfall: Naechtliche Security-Scans

Ein besonders verbreiteter Anwendungsfall fuer Scheduled Pipelines sind vollstaendige Security-Scans, die tagsueber zu lange dauern wuerden, um sie bei jedem Push auszufuehren. Waehrend ein schneller SAST-Scan durchaus bei jedem Merge Request Sinn ergibt, kann ein umfassender Dependency- oder Container-Scan mit vollstaendiger Datenbank-Aktualisierung mehrere Minuten in Anspruch nehmen. Ein naechtlicher Schedule um zwei oder drei Uhr sorgt dafuer, dass diese Grundlichkeit trotzdem taeglich stattfindet, ohne die Entwickler-Feedback-Schleife tagsueber zu verlangsamen.

Ergaenzend bietet es sich an, das Ergebnis eines solchen naechtlichen Scans automatisiert in einen Slack-Kanal oder per E-Mail an das Security-Team zu senden, wenn neue kritische Findings auftauchen, statt sich darauf zu verlassen, dass jemand taeglich manuell in die Pipeline-Uebersicht schaut. Ein einfacher Job am Ende der Pipeline, der bei Fehlschlag eine Webhook-Benachrichtigung ausloest, schliesst diese Lücke zuverlaessig und stellt sicher, dass kritische Funde nicht erst Tage spaeter auffallen.


# .gitlab-ci.yml
notify-on-finding:
  stage: notify
  script:
    - |
      if [ "$SCAN_RESULT" = "critical" ]; then
        curl -X POST -H 'Content-type: application/json' \
          --data '{"text":"Kritischer Security-Fund im naechtlichen Scan"}' \
          "$SLACK_WEBHOOK_URL"
      fi
  rules:
    - if: '$CI_PIPELINE_SOURCE == "schedule"'
  needs: ["dependency-scan"]

8. Anwendungsfall: Wiederkehrende Wartungsjobs

Neben Security-Scans eignen sich Scheduled Pipelines hervorragend fuer Wartungsaufgaben, die regelmaessig, aber nicht bei jedem Commit erfolgen sollen. Beispiele sind das Aufraeumen alter, nicht mehr benoetigter Docker-Images in der eigenen Container-Registry, das Loeschen abgelaufener Feature-Branch-Umgebungen, das Erneuern von SSL-Zertifikaten ueber Let's Encrypt oder das Erstellen und Verifizieren regelmaessiger Datenbank-Backups mit anschliessendem Restore-Test in einer isolierten Umgebung.

Der Vorteil gegenueber einem externen Cron-Tool ist, dass diese Wartungsjobs direkt im selben Repository und in derselben Versionierung wie der restliche Anwendungscode liegen. Aenderungen an der Backup-Strategie oder der Bereinigungslogik durchlaufen denselben Merge-Request-Review-Prozess wie jede andere Code-Aenderung, was die Nachvollziehbarkeit und Qualitaetssicherung fuer sicherheitsrelevante Wartungsaufgaben deutlich verbessert im Vergleich zu einem isoliert gepflegten Skript auf irgendeinem Server.

9. Best Practices und Vergleich mit Alternativen

Ein solider Umgang mit Scheduled Pipelines beginnt damit, jeden Schedule mit einer aussagekraeftigen Beschreibung zu versehen und regelmaessig zu pruefen, ob er noch benoetigt wird. Verwaiste Schedules, deren urspruengliche Aufgabe laengst obsolet ist, verbrauchen unnoetig CI-Minuten und sorgen fuer Verwirrung. Ebenso wichtig ist, Fehlschlaege von Scheduled Pipelines nicht stillschweigend zu ignorieren, sondern eine Benachrichtigung einzurichten, da sonst ein nächtlicher Sicherheitsscan wochenlang unbemerkt fehlschlagen kann.

Im Vergleich zu Alternativen wie einem klassischen Server-Cronjob oder einem Kubernetes CronJob-Objekt bietet GitLab den Vorteil der einheitlichen Oberflaeche, der Versionierung der Job-Definition im selben Repository und der nahtlosen Integration in bestehende Pipeline-Variablen und Secrets. Die folgende Tabelle stellt die drei Ansaetze anhand ihrer wichtigsten Eigenschaften gegenueber, um die Entscheidung fuer den jeweiligen Anwendungsfall zu erleichtern.

Ansatz Ausfuehrungsort Nachvollziehbarkeit Typischer Einsatz
GitLab Scheduled Pipeline GitLab-Runner, containerisiert Volle Pipeline-Historie und Logs Naechtliche Scans, Repository-nahe Wartung
Server-Cronjob (crontab) Direkt auf dem Zielserver Nur Logdatei oder Mail an root Serverlokale Aufgaben ohne Container-Overhead
Kubernetes CronJob Innerhalb des Kubernetes-Clusters kubectl logs, Cluster-Events Wiederkehrende Jobs in Cluster-nativen Setups
Externer Scheduler-Dienst Ausserhalb von GitLab und Server Abhaengig vom jeweiligen Tool Cross-System-Orchestrierung ueber mehrere Plattformen

Mironsoft

CI/CD-Pipelines, Zero-Downtime-Deployments und Release-Automatisierung

Deployments, die ohne Ausfallzeit und ohne Nervenkitzel laufen?

Wir prüfen bestehende GitLab-Pipelines auf fragile Deployment-Schritte und fehlende Absicherung und bauen daraus einen Release-Prozess mit Zero-Downtime-Deployments, automatisierten Checks und einem Rollback, dem ihr im Ernstfall vertrauen könnt.

Pipeline-Review

Bestehende .gitlab-ci.yml auf Fragilität, fehlende Stages und Sicherheitslücken prüfen.

Zero-Downtime-Deployment

Symlink-Releases, Health-Checks und Rollback-Strategien für Magento-Shops aufbauen.

CI/CD-Automatisierung

Tests, Security-Scans und Deployments zu einer zuverlässigen Pipeline verbinden.

10. Zusammenfassung

GitLab Scheduled Pipelines: Das Wichtigste auf einen Blick

Zeitgesteuert statt Push

Scheduled Pipelines laufen nach cron-Zeitplan, unabhaengig davon, ob an dem Tag committet wurde.

CI_PIPELINE_SOURCE

Die Variable schedule unterscheidet zeitgesteuerte Laeufe zuverlaessig von normalen Commit-Pipelines.

Kein Server-Cronjob

Scheduled Pipelines laufen containerisiert im Runner, mit voller Log- und Artifact-Historie in GitLab.

Typische Anwendungsfaelle

Naechtliche Security-Scans, Registry-Aufraeumung, Backup-Verifikation und Zertifikatserneuerung.

11. FAQ: GitLab Scheduled Pipelines: Das Wichtigste auf einen Blick

1Wo lege ich einen Scheduled Pipeline in GitLab an?
Unter Build > Pipeline schedules im Projekt. Dort werden Beschreibung, cron-Ausdruck, Zeitzone, Ziel-Branch und optionale, nur fuer diesen Schedule geltende Variablen konfiguriert.
2Wie unterscheidet eine Pipeline zwischen Push und Schedule?
Ueber die vordefinierte Variable CI_PIPELINE_SOURCE. Sie enthaelt bei einem Schedule den Wert schedule, bei einem normalen Commit push und bei einem Merge Request merge_request_event, sodass rules gezielt darauf reagieren koennen.
3Welche cron-Syntax verwendet GitLab?
Die klassische Fuenf-Felder-Syntax mit Minute, Stunde, Tag des Monats, Monat und Wochentag, getrennt durch Leerzeichen. Der Ausdruck 0 2 * * * bedeutet zum Beispiel jeden Tag um zwei Uhr nachts.
4Warum laeuft mein Schedule nicht zur erwarteten Uhrzeit?
Meist liegt es an der beim Anlegen gewaehlten Zeitzone, die unabhaengig von der Serverzeitzone ist. Bei GitLab.com wird standardmaessig UTC verwendet, was zu einer scheinbaren Verschiebung fuehren kann, wenn die eigene Zielzeitzone nicht explizit gesetzt wurde.
5Ist eine Scheduled Pipeline ein Ersatz fuer einen Server-Cronjob?
Nicht generell. Fuer Aufgaben, die direkt auf einem bestimmten Server ohne Container-Overhead laufen muessen, bleibt ein klassischer Cronjob geeigneter. Fuer repository-nahe, versionierte Aufgaben mit voller Pipeline-Nachvollziehbarkeit ist die Scheduled Pipeline die bessere Wahl.
6Kann ich mehrere Schedules fuer dasselbe Projekt anlegen?
Ja, ein Projekt kann beliebig viele Schedules mit unterschiedlichen cron-Ausdruecken, Ziel-Branches und Variablen haben, zum Beispiel einen taeglichen Quick-Scan und einen woechentlichen Deep-Scan parallel.
7Wie teste ich einen neu angelegten Schedule, ohne auf den naechsten Zeitpunkt zu warten?
Ueber den Button Run now in der Schedule-Uebersicht laesst sich der Schedule jederzeit manuell ausloesen, mit denselben Variablen und Einstellungen, die auch beim automatischen cron-Lauf verwendet wuerden.
8Wie werde ich benachrichtigt, wenn eine Scheduled Pipeline fehlschlaegt?
GitLab bietet projektweite E-Mail-Benachrichtigungen bei fehlgeschlagenen Pipelines. Zusaetzlich laesst sich ein eigener Job einrichten, der bei Fehlschlag gezielt einen Webhook an Slack oder ein anderes Tool sendet.
9Verbrauchen Scheduled Pipelines CI-Minuten wie normale Pipelines?
Ja, ein zeitgesteuerter Lauf verbraucht dieselben CI/CD-Minuten wie jede andere Pipeline. Verwaiste oder zu haeufig laufende Schedules sollten deshalb regelmaessig ueberprueft und bei Bedarf deaktiviert werden.
10Kann ich Scheduled-Pipeline-Variablen in normalen Pipelines wiederverwenden?
Nein, Variablen, die direkt am Schedule hinterlegt sind, gelten ausschliesslich fuer diesen konkreten zeitgesteuerten Lauf. Fuer projektweit geltende Werte sollten stattdessen normale CI/CD-Variablen in den Projekteinstellungen verwendet werden.