From 284b187097d0c1313b34e455d60f8c0dc70fff34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Rossi?= Date: Thu, 16 Jul 2026 14:26:49 +0200 Subject: [PATCH] improved containers status check --- .gitea/workflows/deploy-env-dns.yml | 83 +++++++++++++++++++++-------- 1 file changed, 61 insertions(+), 22 deletions(-) diff --git a/.gitea/workflows/deploy-env-dns.yml b/.gitea/workflows/deploy-env-dns.yml index f213fd5..536d912 100644 --- a/.gitea/workflows/deploy-env-dns.yml +++ b/.gitea/workflows/deploy-env-dns.yml @@ -26,6 +26,11 @@ on: required: false type: string default: "" + health-timeout-seconds: + description: "Secondi massimi di attesa che tutti i container diventino running/healthy dopo il deploy" + required: false + type: string + default: "180" jobs: deploy: @@ -288,41 +293,75 @@ jobs: REMOTE_PATH="${DEPLOY_BASE_PATH}/${{ github.repository_owner }}/${{ github.event.repository.name }}" COMPOSE="docker-compose-${ENV_NAME}.yml" ENV_FILE=".env_${ENV_NAME}" + TIMEOUT="${{ inputs.health-timeout-seconds }}" CBASE="cd ${REMOTE_PATH} && DOCKER_CONFIG=/tmp/.docker-ci docker compose -f ${COMPOSE}" [ -f "$ENV_FILE" ] && CBASE="${CBASE} --env-file ${ENV_FILE}" - echo "── Container status ──" + echo "── Container status (iniziale) ──" ssh ${DEPLOY_USER}@${HOST} "${CBASE} ps" - # Verifica reale (non solo informativa): se un servizio non è "running" - # o risulta "unhealthy", lo step fallisce e innesca il rollback. + # Attende che tutti i container siano "running" e, se hanno un + # healthcheck definito, "healthy" - non basta una fotografia subito + # dopo "up -d", che coglie quasi sempre i servizi ancora in + # "starting" (specie servizi Java/Spring con avvio lento). Fallisce + # subito se un servizio è "unhealthy" o non "running" (nessuna + # attesa inutile), altrimenti continua a interrogare fino a TIMEOUT. ssh ${DEPLOY_USER}@${HOST} " set -e - ids=\$(${CBASE} ps -q) - if [ -z \"\$ids\" ]; then - echo 'ERRORE: nessun container in esecuzione dopo il deploy.' - exit 1 - fi - fail=0 - for cid in \$ids; do - svc=\$(docker inspect -f '{{ index .Config.Labels \"com.docker.compose.service\" }}' \$cid 2>/dev/null) - [ -z \"\$svc\" ] && svc=\$cid - status=\$(docker inspect -f '{{.State.Status}}' \$cid) - health=\$(docker inspect -f '{{if .State.Health}}{{.State.Health.Status}}{{else}}n/a{{end}}' \$cid) - echo \"Servizio \$svc: status=\$status health=\$health\" - if [ \"\$status\" != 'running' ]; then - echo \"ERRORE: servizio \$svc non e' in stato running.\" - fail=1 + TIMEOUT=${TIMEOUT} + INTERVAL=5 + elapsed=0 + while true; do + ids=\$(${CBASE} ps -q) + if [ -z \"\$ids\" ]; then + echo 'ERRORE: nessun container in esecuzione dopo il deploy.' + exit 1 fi - if [ \"\$health\" = 'unhealthy' ]; then - echo \"ERRORE: servizio \$svc risulta unhealthy.\" - fail=1 + fail=0 + pending=0 + for cid in \$ids; do + svc=\$(docker inspect -f '{{ index .Config.Labels \"com.docker.compose.service\" }}' \$cid 2>/dev/null) + [ -z \"\$svc\" ] && svc=\$cid + status=\$(docker inspect -f '{{.State.Status}}' \$cid) + health=\$(docker inspect -f '{{if .State.Health}}{{.State.Health.Status}}{{else}}n/a{{end}}' \$cid) + if [ \"\$status\" != 'running' ]; then + echo \"ERRORE: servizio \$svc non e' in stato running (status=\$status).\" + fail=1 + elif [ \"\$health\" = 'unhealthy' ]; then + echo \"ERRORE: servizio \$svc risulta unhealthy.\" + fail=1 + elif [ \"\$health\" = 'starting' ]; then + pending=1 + fi + done + + if [ \"\$fail\" -eq 1 ]; then + echo '── Stato al momento del fallimento ──' + ${CBASE} ps + exit 1 fi + + if [ \"\$pending\" -eq 0 ]; then + echo 'Tutti i servizi sono running e (se previsto) healthy.' + break + fi + + if [ \"\$elapsed\" -ge \"\$TIMEOUT\" ]; then + echo \"ERRORE: timeout (\${TIMEOUT}s) in attesa che tutti i servizi diventino healthy.\" + ${CBASE} ps + exit 1 + fi + + echo \"In attesa che i servizi diventino healthy... (\${elapsed}s/\${TIMEOUT}s)\" + sleep \$INTERVAL + elapsed=\$((elapsed + INTERVAL)) done - exit \$fail " + echo "── Container status (finale) ──" + ssh ${DEPLOY_USER}@${HOST} "${CBASE} ps" + # ───────────────────────────────────────────────────────────── # HOSTS: dopo un deploy riuscito, recuperiamo l'IP del container # FE (label type=FE) e ci assicuriamo che /etc/hosts sul server