Déployer avec GitLab CI et redémarrer une commande¶
Cet exemple compile un projet Node.js, envoie le résultat par SFTP avec mot de passe et redémarre une commande Zaroz Cloud via l'API du Kernel. Le mot de passe SFTP transfère les fichiers ; un jeton API fin et séparé contrôle uniquement le redémarrage.
Tu peux consulter Get Order Status et Toggle Order dans la référence OpenAPI du Kernel.
Ce qu'il te faut¶
Depuis le tableau de bord de la commande, récupère l'hôte, le port, l'utilisateur, le mot de passe et le chemin SFTP.
Crée un jeton dédié avec ces deux autorisations, toutes deux limitées à cette commande précise :
orders.read— permet au job d'attendre l'arrêt du serveur.orders.server.toggle— permet de l'arrêter et de le démarrer.
Ne lui donne aucun accès au terminal, à la facturation, aux bases de données ou à toutes les commandes.
Ajouter les variables CI/CD protégées¶
Dans GitLab, ouvre Settings → CI/CD → Variables et ajoute :
| Variable | Type | Options conseillées |
|---|---|---|
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 |
Génère ZAROZ_SFTP_KNOWN_HOSTS depuis une machine de confiance et vérifie l'empreinte de l'hôte. N'utilise pas StrictHostKeyChecking=no dans une pipeline de production.
Protège l'environnement de déploiement
Les variables protégées ne sont disponibles que pour les branches ou tags protégés. Protège aussi l'environnement de production pour qu'une merge request non fiable ne puisse pas extraire les identifiants.
Ajouter .gitlab-ci.yml¶
L'exemple suppose que npm run build produit un dossier dist/. Adapte la commande et le dossier à ton projet.
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"
Pourquoi attendre entre l'arrêt et le démarrage¶
L'endpoint change l'état souhaité, mais Kubernetes a encore besoin de temps pour arrêter la charge. Redémarrer immédiatement peut entrer en concurrence avec la terminaison. Lire l'état évite cette course et donne une erreur claire dans GitLab.
Si ton logiciel sait se recharger proprement, préfère cette méthode. Un cycle arrêt/démarrage interrompt les joueurs ou utilisateurs actifs.
Adapter l'envoi¶
Le lot SFTP écrase les fichiers correspondants, mais ne supprime pas les fichiers distants absents de dist/. Pour un miroir exact, déploie dans des dossiers versionnés et bascule la version active depuis le script de démarrage de ton application.
N'envoie jamais de secrets depuis le dépôt. Garde-les dans le tableau de bord Zaroz ou dans des variables CI/CD protégées.
Dépannage¶
L'API renvoie 403
Vérifie que les deux autorisations ciblent l'UUID de ZAROZ_ORDER_ID et que le propriétaire du jeton peut encore contrôler la commande.
SFTP signale une erreur de clé d'hôte
Mets ZAROZ_SFTP_KNOWN_HOSTS à jour uniquement après avoir vérifié la nouvelle empreinte par un canal de confiance.
L'envoi fonctionne, mais pas le redémarrage
Vérifie orders.server.toggle en plus de orders.read, ainsi que l'expiration du jeton.
Le serveur reste en Stopping plus de 60 secondes
Laisse le job échouer au lieu de basculer l'état en boucle. Inspecte la commande dans le tableau de bord et relance après l'arrêt complet.