Files
dependency-track/.woodpecker.yml
syoul c62000112f
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
fix(ci): docker compose stop avant acme.sh — deregistre les conteneurs de Registrator/Fabio
2026-03-19 14:56:10 +01:00

133 lines
5.6 KiB
YAML

when:
- branch: main
event: push
steps:
# Etape 1 : Ecriture du .env.deploy depuis les secrets
# NOTE: ne pas utiliser ${VAR} dans commands (bug Woodpecker next), utiliser env | grep
# NOTE: from_secret et volumes incompatibles dans le meme step (bug Woodpecker next)
- name: write-env
image: alpine:3.20
environment:
DTRACK_DOMAIN:
from_secret: dtrack_domain
commands:
- env | grep -E "^(DTRACK_DOMAIN)=" > .env.deploy
# COMPOSE_PROJECT_NAME : convention user-project-branch, genere depuis les vars CI
- OWNER=$(echo "$CI_REPO_OWNER" | tr 'A-Z' 'a-z') && REPO=$(echo "$CI_REPO_NAME" | tr 'A-Z' 'a-z') && BRANCH=$(echo "$CI_COMMIT_BRANCH" | tr 'A-Z/' 'a-z-') && echo "COMPOSE_PROJECT_NAME=$OWNER-$REPO-$BRANCH" >> .env.deploy
- echo "Fichier .env.deploy cree ($(wc -c < .env.deploy) octets)"
# TEST write-env : valide le contenu du .env.deploy
- name: test-env
image: alpine:3.20
commands:
- |
if [ ! -f .env.deploy ]; then
echo "FAIL: .env.deploy introuvable dans le workspace"
exit 1
fi
echo "PASS: .env.deploy present"
- |
VAL=$(grep '^COMPOSE_PROJECT_NAME=' .env.deploy | cut -d= -f2)
[ -z "$VAL" ] && echo "FAIL: COMPOSE_PROJECT_NAME vide" && exit 1
echo "PASS: COMPOSE_PROJECT_NAME = $VAL"
VAL=$(grep '^DTRACK_DOMAIN=' .env.deploy | cut -d= -f2)
[ -z "$VAL" ] && echo "FAIL: DTRACK_DOMAIN vide" && exit 1
echo "PASS: DTRACK_DOMAIN = $VAL"
# Etape 2 : Deploiement sur sonic via Docker socket
# L'agent Woodpecker tourne sur sonic — pas de SSH requis
- name: deploy
image: docker:27-cli
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /opt/dtrack:/opt/dtrack
commands:
- cp .env.deploy /opt/dtrack/.env
- chmod 600 /opt/dtrack/.env
- cp docker-compose.yml /opt/dtrack/docker-compose.yml
- echo "=== config resolue ==="
- cd /opt/dtrack && docker compose config
- echo "=== pull ==="
- cd /opt/dtrack && docker compose pull --no-parallel
- echo "=== stop (deregistre Registrator avant challenge ACME) ==="
- cd /opt/dtrack && docker compose stop
- |
DOMAIN=$(grep '^DTRACK_DOMAIN=' /opt/dtrack/.env | cut -d= -f2)
# --- Certificat TLS ---
# Apres docker compose stop : Registrator a deregistre les conteneurs de Fabio.
# La route globale */.well-known/acme-challenge/* peut repondre sans interference.
# Exit 0 = emis/renouvele, exit 2 = skip (cert valide), autres = erreur
ACME_EXIT=0
docker exec sonic-acme-1 /app/acme.sh \
--home /etc/acme.sh \
--issue -d "$DOMAIN" \
--webroot /usr/share/nginx/html \
--server letsencrypt \
--accountemail support+acme@asycn.io || ACME_EXIT=$?
if [ "$ACME_EXIT" -ne 0 ] && [ "$ACME_EXIT" -ne 2 ]; then
echo "ERREUR: acme.sh a echoue (exit $ACME_EXIT)"
exit 1
fi
docker exec sonic-acme-1 cp /etc/acme.sh/$DOMAIN/fullchain.cer /host/certs/$DOMAIN-cert.pem
docker exec sonic-acme-1 cp /etc/acme.sh/$DOMAIN/$DOMAIN.key /host/certs/$DOMAIN-key.pem
echo "Cert TLS: /host/certs/$DOMAIN-cert.pem OK (acme exit $ACME_EXIT)"
- echo "=== up ==="
- cd /opt/dtrack && docker compose up -d --remove-orphans
- cd /opt/dtrack && docker compose ps
# Fabio routing gere automatiquement par Registrator via les labels SERVICE_* du compose
# TEST deploy : verifie que les conteneurs sont running
# NOTE: pas de ${VAR} (substitue par Woodpecker) — utiliser $VAR sans accolades
- name: test-deploy
image: docker:27-cli
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /opt/dtrack:/opt/dtrack
commands:
- |
PROJECT=$(grep '^COMPOSE_PROJECT_NAME=' /opt/dtrack/.env | cut -d= -f2)
STATUS=$(docker inspect --format '{{.State.Status}}' "$PROJECT-apiserver" 2>/dev/null || echo "absent")
echo "$PROJECT-apiserver : $STATUS"
[ "$STATUS" = "running" ] || { echo "FAIL: apiserver non running"; exit 1; }
echo "PASS: apiserver running"
STATUS=$(docker inspect --format '{{.State.Status}}' "$PROJECT-frontend" 2>/dev/null || echo "absent")
echo "$PROJECT-frontend : $STATUS"
[ "$STATUS" = "running" ] || { echo "FAIL: frontend non running"; exit 1; }
echo "PASS: frontend running"
# Etape 3 : Healthcheck via Docker — poll le statut interne du conteneur
# Pas de requete HTTPS publique : Fabio/TLS ne sont pas encore configures ici
- name: healthcheck
image: docker:27-cli
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /opt/dtrack:/opt/dtrack
commands:
- |
PROJECT=$(grep '^COMPOSE_PROJECT_NAME=' /opt/dtrack/.env | cut -d= -f2)
echo "Attente healthcheck Docker sur $PROJECT-apiserver (max 5 min)..."
MAX=30
i=0
until [ $i -ge $MAX ]; do
HEALTH=$(docker inspect --format '{{.State.Health.Status}}' "$PROJECT-apiserver" 2>/dev/null || echo "absent")
echo "Tentative $((i+1))/$MAX — $PROJECT-apiserver : $HEALTH"
[ "$HEALTH" = "healthy" ] && echo "PASS: apiserver healthy" && exit 0
[ "$HEALTH" = "absent" ] && echo "FAIL: conteneur introuvable" && exit 1
i=$((i+1))
sleep 10
done
echo "FAIL: apiserver non healthy apres 5 minutes"
exit 1
# Notification en cas d'echec
- name: notify-failure
image: alpine:3.20
commands:
- 'echo "ECHEC pipeline #$CI_BUILD_NUMBER sur commit $CI_COMMIT_SHA"'
- 'echo "Branche: $CI_COMMIT_BRANCH"'
when:
- status: failure