Implementar com GitLab CI e reiniciar uma encomenda¶
Este exemplo compila um projeto Node.js, envia o resultado por SFTP com palavra-passe e reinicia uma encomenda da Zaroz Cloud através da API do Kernel. A palavra-passe SFTP transfere os ficheiros; um token de API detalhado e separado controla apenas o reinício.
Podes consultar Get Order Status e Toggle Order na referência OpenAPI do Kernel.
O que precisas¶
No painel da encomenda, recolhe o anfitrião, porto, utilizador, palavra-passe e caminho SFTP.
Cria um token dedicado com estas duas autorizações, ambas limitadas à encomenda exata:
orders.read— permite esperar que o servidor pare.orders.server.toggle— permite parar e iniciar o servidor.
Não atribuas acesso ao terminal, faturação, bases de dados ou a todas as encomendas.
Adicionar variáveis CI/CD protegidas¶
No GitLab, abre Settings → CI/CD → Variables e adiciona:
| Variável | Tipo | Opções 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 |
Gera ZAROZ_SFTP_KNOWN_HOSTS num computador de confiança e confirma a impressão digital do anfitrião. Não uses StrictHostKeyChecking=no numa pipeline de produção.
Protege o ambiente de implementação
As variáveis protegidas só estão disponíveis para branches ou tags protegidos. Protege também o ambiente de produção para que um merge request não fiável não consiga extrair credenciais.
Adicionar .gitlab-ci.yml¶
O exemplo espera que npm run build produza a pasta dist/. Adapta o comando e a pasta ao teu projeto.
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"
Porque espera entre parar e iniciar¶
O endpoint altera o estado pretendido, mas o Kubernetes ainda precisa de tempo para terminar a carga. Iniciar imediatamente pode competir com a terminação. Consultar o estado evita essa corrida e deixa um erro útil no GitLab.
Se o teu software suporta recarregamento gradual, prefere-o. Um ciclo de paragem e arranque interrompe jogadores ou utilizadores ativos.
Adaptar o envio¶
O lote SFTP substitui ficheiros correspondentes, mas não elimina ficheiros remotos que desapareceram de dist/. Para um espelho exato, implementa em pastas com versão e muda a versão ativa no script de arranque da aplicação.
Nunca envies segredos a partir do repositório. Guarda-os no painel Zaroz ou em variáveis CI/CD protegidas.
Resolução de problemas¶
A API devolve 403
Confirma que ambas as autorizações usam o UUID em ZAROZ_ORDER_ID e que o proprietário do token ainda pode controlar a encomenda.
O SFTP apresenta um erro de chave do anfitrião
Atualiza ZAROZ_SFTP_KNOWN_HOSTS apenas depois de confirmares a nova impressão digital por um canal de confiança.
O envio funciona, mas o reinício não
Confirma orders.server.toggle, além de orders.read, e verifica se o token expirou.
O servidor fica em Stopping mais de 60 segundos
Deixa o job falhar em vez de alternar repetidamente. Inspeciona a encomenda no painel e repete depois da paragem completa.