Aller au contenu

Chaîne CI/CD (Forgejo + Woodpecker)

Le homelab héberge sa propre forge et sa propre intégration continue, en logiciels libres, sur deux CT LXC du VLAN 10. C'est ce qui héberge les dépôts (infra, docs…) et vérifie chaque push — y compris celui de ce portail.

Rôle Machine Adresse Logiciel
Forge Git CT 110 forgejo (2 vCPU / 2 Go, disque 16 Go) http://10.9.73.81:3000 · SSH 2222 Forgejo 15.0.4
CI CT 111 ci (4 vCPU / 3 Go, disque 24 Go) http://10.9.73.82:8000 Woodpecker 3.16.0

Les deux CT sont créés par OpenTofu (opentofu/ct-forgejo-ci.tf) et configurés par Ansible (ansible/playbooks/forgejo.yml, ci.yml). LXC Debian 12 non privilégiés ; le CT ci a l'option nesting activée pour faire tourner Docker (backend des étapes de pipeline).

Le flux

  git push ──▶ Forgejo (10.9.73.81)
                  │  webhook (ALLOWED_HOST_LIST = 10.9.73.82)
                  ▼
              Woodpecker server (10.9.73.82:8000)
                  │  gRPC :9000
                  ▼
              Woodpecker agent ──▶ étapes en conteneurs Docker
                  │
                  ▼  statut du build renvoyé
              Forgejo (coche verte / croix rouge sur le commit)
  1. Un push (ou une PR) sur un dépôt Forgejo déclenche un webhook vers Woodpecker. Forgejo bloque par défaut les webhooks vers les IP privées : l'IP du CI est explicitement autorisée (ALLOWED_HOST_LIST = 10.9.73.82 dans app.ini).
  2. Le server Woodpecker lit le fichier .woodpecker/*.yaml du dépôt et planifie les étapes.
  3. L'agent (même CT) exécute chaque étape dans un conteneur Docker (WOODPECKER_BACKEND=docker, 2 workflows en parallèle au plus).
  4. Le résultat est renvoyé à Forgejo et s'affiche sur le commit / la PR.

L'authentification de Woodpecker se fait via Forgejo (OAuth2, WOODPECKER_FORGEJO=true) : on se connecte au CI avec son compte de la forge. L'inscription ouverte est désactivée des deux côtés (DISABLE_REGISTRATION, WOODPECKER_OPEN=false).

Ce qui tourne dessus

  • infra — pipeline .woodpecker/ci.yaml : tofu fmt -check, tofu validate, ansible-lint (non bloquant pour l'instant). Le tofu plan en CI viendra quand la clé age sera disponible sur le runner.
  • docs (ce portail) — mkdocs build --strict : un lien mort fait échouer le build. Le déploiement est ensuite pris en charge par Coolify (cf. Ce site).

Persistance et secrets

  • Données : chacun stocke en SQLite local (/var/lib/forgejo/data, /var/lib/woodpecker). Ces CT sont donc sauvegardés par le vzdump quotidien comme les autres.
  • Secrets (mot de passe admin Forgejo, clés OAuth, AGENT_SECRET…) : chiffrés avec sops dans secrets/services.enc.env, injectés au moment de jouer les playbooks (sops exec-env). Voir le runbook Secrets.

Exploitation

Les services sont des unités systemd (binaires, pas de conteneur pour la forge et le server/agent) :

# Sur le CT forgejo (10.9.73.81)
systemctl status forgejo
journalctl -u forgejo -f

# Sur le CT ci (10.9.73.82)
systemctl status woodpecker-server woodpecker-agent docker
journalctl -u woodpecker-agent -f

Rejouer la configuration (idempotent) depuis ~/projets/infra sur dev-laravel :

sops exec-env secrets/services.enc.env \
  'ansible-playbook ansible/playbooks/forgejo.yml'   # ou ci.yml

Mettre à jour Forgejo ou Woodpecker

Changer forgejo_version / woodpecker_version en tête du playbook, puis rejouer : Ansible télécharge le nouveau binaire et redémarre le service. Faire un test de restauration du CT avant une montée de version majeure de Forgejo (migrations de schéma SQLite).