"Ce qu'une simple mise à jour Woodpecker a révélé sur mon homelab"
Le plan initial
Woodpecker affiche un bandeau dans son UI quand une mise à jour est disponible, ça semblait être 30 minutes, le plan: un snapshot Proxmox, quelques commandes, terminé.
Ça ne s'est pas passé comme ça.
Première surprise : les snapshots Proxmox
Réflexe avant toute intervention : snapshot du container LXC. Je lance :
pct snapshot <ID> before-woodpecker-vX.Y.Z
Proxmox refuse. 400 Parameter verification failed. Les tirets ne sont pas acceptés dans les noms de snapshots — uniquement les caractères alphanumériques et les underscores.
pct snapshot <ID> before_woodpecker_vX_Y_Z --description "avant update woodpecker vX.Y.Z"
Détail bête, mais pas documenté clairement. Je mets à jour ma doc en conséquence.
Deuxième surprise : pas de service systemd
Sur mon infra maison, le server Woodpecker tourne en Docker — jusque-là normal. Mais l'agent, lui, tourne en binaire natif sur une autre machine. En voulant l'arrêter :
systemctl stop woodpecker-agent
Failed to stop woodpecker-agent.service: Unit woodpecker-agent.service not loaded.
Le service systemd n'existait pas. L'agent tournait depuis un process lancé à la main... Un crash ou un reboot et il ne redémarre pas. Ça tenait par chance.
C'était mon premier lab, dès que le pipeline était opérationnel, j'ai voulu le tester sur quelques projets si bien que j'ai fini par oublier que le service n'avait pas été créé.
Comment retrouver la configuration?
Tout seul, mes actions sont vite limitées... Ici Claude Code est un bon allié, il a plein de pistes à proposer.
L'objectif, récupérer la config depuis le process qui tourne.
La configuration était uniquement dans les variables d'environnement du process. Linux conserve ça dans /proc :
cat /proc/<PID>/environ | tr '\0' '\n' | grep "^WOODPECKER"
Claude propose une commande "optimisée" pour créer et sauvegarder la configuration:
mkdir -p /etc/woodpecker
cat /proc/<PID>/environ | tr '\0' '\n' | grep "^WOODPECKER" > /etc/woodpecker/woodpecker-agent.env
chmod 600 /etc/woodpecker/woodpecker-agent.env
Création du service systemd
Avec la config sauvegardée, je crée le service pour que l'agent redémarre automatiquement :
[Unit]
Description=Woodpecker CI Agent
After=network.target
[Service]
EnvironmentFile=/etc/woodpecker/woodpecker-agent.env
ExecStart=/usr/local/bin/woodpecker-agent
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable woodpecker-agent
Troisième surprise : le server en Docker occupait le port
En voulant migrer le server Woodpecker en binaire natif aussi, le service systemd ne démarrait pas. Le port était déjà pris :
failed to listen on grpc-addr: listen tcp :xxxx: bind: address already in use
C'était Docker qui tenait le port — le container Woodpecker server était toujours là.
À ce stade j'ai posé la vraie question : pourquoi migrer le server en natif alors qu'il tourne bien en Docker ? Aucune bonne raison. Je reviens sur ma décision et je fais simplement la mise à jour de l'image Docker :
image: woodpeckerci/woodpecker-server:vX.Y.Z
docker compose pull && docker compose up -d
Avec le recul, j'avais complètement oublié que l'installation initiale du server passait déjà par Docker. Je suis parti dans une migration vers du natif un peu trop vite, avant de me demander si ce changement avait réellement un intérêt.
La vraie correction était beaucoup plus simple : mettre à jour l'image Docker existante .
Une centaine d'agents fantômes à nettoyer
Les redémarrages ratés de l'agent ont généré autant d'entrées dans la base de données Woodpecker. On s'est retrouvé avec une centaine d'agents fantômes dans l'UI. Un script bash pour nettoyer via l'API :
for id in $(seq 4 125); do
curl -s -X DELETE -H "Authorization: Bearer TOKEN" \
"https://ui_du_woodpecker.tld/api/agents/$id"
done
Quand on y pense, c'est fort quand même, exécuter une boucle comme ça en bash directement dans le terminal.
Claude m'indique des pistes pour éviter la création de ces agents fantômes à l'avenir.
Soit jouer avec les paramètres max-retry ou on-failure dans le
docker-compose.yml restart: "on-failure:5".
Soit faire une création manuelle: créer un agent dans l'UI du serveur. On récupère l'ID et le Token fixe pour les passer à l'agent Docker, il utilisera ainsi toujours le même ID. Le trade-off ici, on perd en automatisation.
Ce que j'ai appris
- Les noms de snapshots Proxmox n'acceptent pas les tirets
- Vérifier que tous les services critiques ont un
.service /proc/<PID>/environpermet de récupérer la config d'un process sans fichier de config
Le mot de la fin
Une mise à jour de 30 minutes qui en a pris beaucoup plus. Et c'est principalement dû à un problème de documentation.
Documenter encore et toujours, ce n'est pas un exercice facile. Et c'est encore plus difficile quand on découvre en testant en même temps.
À chaque itération, il faut s'efforcer d'améliorer la documentation.