Despliega con GitLab CI y reinicia un pedido¶
Este ejemplo compila un proyecto Node.js, sube el resultado por SFTP con contraseña y reinicia un pedido de Zaroz Cloud mediante la API del Kernel. La contraseña SFTP transfiere archivos; un token de API granular e independiente solo controla el reinicio.
Puedes consultar Get Order Status y Toggle Order en la referencia OpenAPI del Kernel.
Qué necesitas¶
Desde el panel del pedido, obtén el host, puerto, usuario, contraseña y ruta de destino SFTP.
Crea un token dedicado con estos dos permisos, ambos limitados al pedido exacto:
orders.read: permite esperar a que el servidor se detenga.orders.server.toggle: permite detenerlo y arrancarlo.
No le des acceso a terminal, facturación, bases de datos ni a todos los pedidos.
Añade variables CI/CD protegidas¶
En GitLab, abre Settings → CI/CD → Variables y añade:
| Variable | Tipo | Opciones recomendadas |
|---|---|---|
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 |
Genera ZAROZ_SFTP_KNOWN_HOSTS desde un equipo de confianza y comprueba la huella del host antes de guardarlo. No uses StrictHostKeyChecking=no en producción.
Protege el entorno de despliegue
Las variables protegidas solo se entregan a ramas o tags protegidos. Protege también el entorno de producción para que un merge request no fiable no pueda extraer las credenciales.
Añade .gitlab-ci.yml¶
El ejemplo espera que npm run build genere dist/. Adapta ambos a tu proyecto.
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"
Por qué espera entre detener y arrancar¶
El endpoint cambia el estado deseado, pero Kubernetes aún necesita tiempo para apagar la carga. Arrancar de inmediato puede competir con la terminación. Consultar el estado evita esa carrera y deja un error útil en GitLab.
Si tu software admite una recarga gradual, prefiérela. Un ciclo de parada y arranque interrumpe a jugadores o usuarios activos.
Adapta la subida¶
El lote SFTP sobrescribe archivos coincidentes, pero no elimina archivos remotos que ya no estén en dist/. Si necesitas una copia exacta, despliega en directorios versionados y cambia la versión activa desde el script de arranque de tu aplicación.
No subas secretos desde el repositorio. Guárdalos en el panel de Zaroz o como variables CI/CD protegidas.
Solución de problemas¶
La API devuelve 403
Comprueba que ambos permisos están limitados al UUID de ZAROZ_ORDER_ID y que el propietario del token aún puede controlar el pedido.
SFTP muestra un error de clave de host
Actualiza ZAROZ_SFTP_KNOWN_HOSTS solo después de verificar la nueva huella por un canal de confianza.
La subida funciona pero el reinicio no
Comprueba que elegiste orders.server.toggle, además de orders.read, y que el token no ha caducado.
El servidor permanece en Stopping más de 60 segundos
Deja que el job falle en lugar de alternarlo repetidamente. Revisa el pedido en el panel y reintenta cuando termine de detenerse.