Mit GitLab CI ausrollen und eine Bestellung neu starten¶
Dieses Beispiel baut ein Node.js-Projekt, lädt das Ergebnis per passwortgeschütztem SFTP hoch und startet eine Zaroz-Cloud-Bestellung über die Kernel-API neu. Das SFTP-Passwort überträgt Dateien; ein getrenntes, fein abgestuftes API-Token darf nur den Neustart steuern.
Die Endpunkte Get Order Status und Toggle Order findest du in der Kernel-OpenAPI-Referenz.
Voraussetzungen¶
Notiere im Bestell-Dashboard SFTP-Host, Port, Benutzer, Passwort und Zielpfad.
Erstelle ein eigenes API-Token mit genau diesen beiden Freigaben für genau diese Bestellung:
orders.read– der Job kann auf den Stillstand warten.orders.server.toggle– der Job kann den Server stoppen und starten.
Vergib weder Terminal-, Abrechnungs- oder Datenbankzugriff noch kontoweite Rechte.
Geschützte CI/CD-Variablen anlegen¶
Öffne in GitLab Settings → CI/CD → Variables und füge hinzu:
| Variable | Typ | Empfohlene Optionen |
|---|---|---|
ZAROZ_API_TOKEN |
Variable | Masked, protected |
ZAROZ_ORDER_ID |
Variable | Protected |
ZAROZ_SFTP_HOST |
Variable | Protected |
ZAROZ_SFTP_PORT |
Variable | Protected |
ZAROZ_SFTP_USER |
Variable | Protected |
ZAROZ_SFTP_PATH |
Variable | Protected |
ZAROZ_SFTP_PASSWORD |
Variable | Masked, protected |
ZAROZ_SFTP_KNOWN_HOSTS |
File | Protected |
Erzeuge ZAROZ_SFTP_KNOWN_HOSTS auf einem vertrauenswürdigen Rechner und prüfe den Host-Fingerabdruck. Verwende in einer Deployment-Pipeline niemals StrictHostKeyChecking=no.
Deployment-Umgebung schützen
Geschützte Variablen stehen nur geschützten Branches oder Tags zur Verfügung. Schütze auch die Produktionsumgebung, damit ein fremder Merge Request keine Credentials auslesen kann.
.gitlab-ci.yml hinzufügen¶
Das Beispiel erwartet, dass npm run build das Verzeichnis dist/ erzeugt. Passe beides an dein Projekt an.
stages:
- build
- deploy
build:
stage: build
image: node:22-alpine
script:
- npm ci
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 hour
deploy-production:
stage: deploy
image: alpine:3.22
needs:
- job: build
artifacts: true
environment:
name: production
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
before_script:
- apk add --no-cache curl jq lftp openssh-client
- install -d -m 700 ~/.ssh
- cp "$ZAROZ_SFTP_KNOWN_HOSTS" ~/.ssh/known_hosts
- chmod 600 ~/.ssh/known_hosts
script:
- |
export LFTP_PASSWORD="$ZAROZ_SFTP_PASSWORD"
lftp -e "
set cmd:fail-exit true;
set sftp:connect-program \"ssh -a -x -o StrictHostKeyChecking=yes\";
open --env-password --user \"$ZAROZ_SFTP_USER\" -p \"$ZAROZ_SFTP_PORT\" \"sftp://$ZAROZ_SFTP_HOST\";
mirror --reverse --verbose --no-perms dist/ \"$ZAROZ_SFTP_PATH\";
bye
"
unset LFTP_PASSWORD
- |
api() {
curl --fail-with-body --silent --show-error \
-H "Authorization: Bearer $ZAROZ_API_TOKEN" \
-H 'Accept: application/json' \
"$@"
}
API="https://kernel.zaroz.cloud/api/v1/orders/$ZAROZ_ORDER_ID"
api -X POST \
-H 'Content-Type: application/json' \
-d '{"active":false}' \
"$API/toggle"
stopped=false
for attempt in $(seq 1 30); do
state="$(api "$API/status" | jq -r '.state')"
echo "Waiting for stop: $state"
case "$state" in
Suspended|NotProvisioned)
stopped=true
break
;;
Failed)
echo "The order entered Failed state; refusing to start it automatically"
exit 1
;;
esac
sleep 2
done
if [ "$stopped" != true ]; then
echo "The order did not stop within 60 seconds"
exit 1
fi
api -X POST \
-H 'Content-Type: application/json' \
-d '{"active":true}' \
"$API/toggle"
echo "Deployment uploaded and start requested"
Warum der Job zwischen Stopp und Start wartet¶
Der Endpunkt ändert den Sollzustand; Kubernetes braucht weiterhin Zeit zum Beenden. Ein sofortiger Start kann mit der Terminierung kollidieren. Die Statusabfrage verhindert dieses Rennen und hinterlässt in GitLab einen verständlichen Fehler.
Unterstützt deine Software einen sanften Reload, solltest du diesen bevorzugen. Ein Stopp/Start unterbricht aktive Spieler oder Benutzer.
Upload anpassen¶
Der SFTP-Batch überschreibt vorhandene Dateien, löscht aber keine entfernten Dateien aus dist/. Für eine exakte Spiegelung kannst du in versionierte Verzeichnisse ausrollen und die aktive Version über dein Startskript umschalten.
Lade keine Secrets aus dem Repository hoch. Bewahre sie im Zaroz-Dashboard oder in geschützten CI/CD-Variablen auf.
Fehlerbehebung¶
Die API antwortet mit 403
Prüfe, ob beide Freigaben auf dieselbe UUID in ZAROZ_ORDER_ID begrenzt sind und der Token-Besitzer die Bestellung weiterhin steuern darf.
SFTP meldet einen Host-Key-Fehler
Aktualisiere ZAROZ_SFTP_KNOWN_HOSTS erst, nachdem du den neuen Fingerabdruck über einen vertrauenswürdigen Kanal geprüft hast.
Upload funktioniert, Neustart aber nicht
Prüfe orders.server.toggle zusätzlich zu orders.read und das Ablaufdatum des Tokens.
Der Server bleibt länger als 60 Sekunden in Stopping
Lass den Job fehlschlagen, statt wiederholt umzuschalten. Prüfe die Bestellung im Dashboard und starte das Deployment nach dem vollständigen Stopp erneut.