alpinux.presentations/deploy/webhook.md
Cédrix 9ecf1973b8 Suivre le nom réel du dépôt : alpinux.presentations
Le dépôt a été créé sur la forge sous le nom alpinux.presentations, et non
alpinux-presentations : adresses de clonage, lien de la page d'accueil et
consignes d'installation sont alignés.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M713yNBL8cssBA1Zri5QLT
2026-10-10 22:06:47 +02:00

9.2 KiB

Déploiement automatique : mise en place côté serveur

Cette page s'adresse aux mainteneurs qui ont un accès SSH à alpinux.org. Les contributeurs n'ont rien à faire ici : leur travail s'arrête à la pull request.

La chaîne est la même que celle du wiki et de www.alpinux.org :

push sur main  →  webhook Gitea  →  https://presentations.alpinux.org/deploy
                                          │  Apache relaie vers 127.0.0.1:9878
                                          ▼
                              service d'écoute (signature HMAC vérifiée)
                                          ▼
deploy-presentations.sh :  git pull  →  npm ci  →  build dans le staging  →  rsync
                                          ▼
                          https://presentations.alpinux.org

Si le build échoue — front matter invalide, image manquante — rien n'est copié : le site en ligne reste celui du dernier build réussi.


Un second service plutôt qu'une nouvelle route

Le service d'écoute du wiki (/opt/wiki-mkdocs/webhook.py) ne connaît qu'un secret et qu'un script. Y ajouter une route aurait demandé de le réécrire, de faire cohabiter deux secrets dans la même unité systemd, et de redémarrer le déploiement du wiki à chaque retouche de celui des présentations.

Ce dépôt apporte donc son propre service, comme www.alpinux.org l'a fait avant lui. Les trois sont des copies du même petit programme :

Site Service systemd Port Secret
wiki wiki-webhook 9876 dans l'unité systemd
www www-webhook 9877 /etc/default/www-webhook
présentations presentations-webhook 9878 /etc/default/presentations-webhook

Chaque dépôt a son secret : celui des présentations n'ouvre pas le déploiement du wiki, et inversement.


Ce qui est installé, et où

Quoi Où
Clone du dépôt /opt/presentations-alpinux/repo
Répertoire de staging /opt/presentations-alpinux/staging
Node.js (LTS, version figée) /opt/presentations-alpinux/node
Script de déploiement (copie) /opt/presentations-alpinux/deploy-presentations.sh
Service d'écoute (copie) /opt/presentations-alpinux/webhook.py
Unité systemd /etc/systemd/system/presentations-webhook.service
Secret HMAC (0600, root) /etc/default/presentations-webhook
Clé de déploiement, lecture seule ~abonnelc/.ssh/id_ed25519_presentations_deploy
DocumentRoot /var/www/clients/client1/web22/web
Journal /var/log/presentations-deploy.log

Fichiers fournis par ce dossier : installer.sh, webhook.py, presentations-webhook.service, apache-vhost.exemple.conf, et ../scripts/deploy-presentations.sh.

Aucun secret n'est dans le dépôt. Le secret du webhook est tiré au hasard sur le serveur par installer.sh ; la clé privée de déploiement y est créée et n'en sort pas.


Installation

Tout tient dans installer.sh, à lancer en root. Il est sans danger de le relancer : chaque étape vérifie d'abord ce qui existe.

sudo bash deploy/installer.sh
  1. Node.js — téléchargé depuis nodejs.org, somme SHA-256 vérifiée, déposé dans /opt/presentations-alpinux/node. Rien n'est ajouté aux dépôts apt du serveur, et pas de Chromium : le build HTML de Marp n'en a pas besoin.
  2. Clé de déploiement — une clé SSH propre à ce dépôt, et un alias gitea-presentations dans ~abonnelc/.ssh/config.
  3. Clone du dépôt. La première fois, le script s'arrête ici et affiche la clé publique : la déclarer dans Gitea, Paramètres → Clés de déploiement du dépôt, sans l'accès en écriture, puis relancer.
  4. Scripts — copie de deploy-presentations.sh et de webhook.py dans /opt/presentations-alpinux, création du journal.
  5. Droit d'écriture sur le DocumentRoot, par une ACL pour abonnelc.
  6. Secret et service — secret tiré au hasard s'il n'existe pas, unité systemd installée et démarrée.
  7. Relais Apache — les deux lignes ProxyPass dans le vhost, puis rechargement d'Apache si la configuration est valide.

Déclarer le webhook dans Gitea

Dans le dépôt alpinux.presentations : Paramètres → Webhooks → Ajouter un webhook → Gitea.

Champ Valeur
URL cible https://presentations.alpinux.org/deploy
Méthode HTTP POST
Type de contenu application/json
Secret la valeur lue par sudo cat /etc/default/presentations-webhook
Déclencheur Push seulement
Filtre de branche main

Le filtre de branche évite des appels inutiles ; le service ignore de toute façon tout ce qui ne vise pas refs/heads/main.

Rendre le relais Apache durable

Le vhost est écrit par ISPConfig, qui le régénère à chaque modification du site (certificat, alias, version de PHP…). Les deux lignes posées par installer.sh disparaissent ce jour-là.

Pour qu'elles tiennent : dans ISPConfig, Sites → presentations.alpinux.org → Options → Directives Apache, coller les deux lignes de apache-vhost.exemple.conf. ISPConfig les réécrira alors avec le reste du vhost.


Vérifier

# Le service tourne et n'écoute que sur la boucle locale
systemctl status presentations-webhook
ss -ltn | grep 9878

# Sans signature valable, le relais répond 403 — c'est la bonne réponse
curl -s -o /dev/null -w '%{http_code}\n' -X POST -d '{}' https://presentations.alpinux.org/deploy

# Le dernier déploiement
tail -20 /var/log/presentations-deploy.log

Une exécution réussie encadre le build par une ligne Deploy started et une ligne Deploy done. Une ligne ABANDON signale un échec : la cause est juste au-dessus, et le site en ligne n'a pas bougé.

Dans Gitea, la page du webhook liste les envois récents avec la réponse reçue, et son bouton Tester l'envoi rejoue un push.


Au quotidien

Je veux… Je fais…
Savoir pourquoi ce n'est pas en ligne tail -30 /var/log/presentations-deploy.log
Republier sans nouveau commit sudo -u abonnelc /opt/presentations-alpinux/deploy-presentations.sh
Appliquer une modification de deploy/ sudo bash /opt/presentations-alpinux/repo/deploy/installer.sh
Changer de version de Node.js modifier NODE_VERSION dans installer.sh, pousser, relancer installer.sh
Changer le secret supprimer /etc/default/presentations-webhook, relancer installer.sh, mettre à jour le webhook dans Gitea

Les pièges à connaître

Le serveur exécute des copies. deploy-presentations.sh et webhook.py sont copiés dans /opt/presentations-alpinux par installer.sh. Les modifier dans le dépôt ne change rien tant que installer.sh n'a pas été relancé. C'est voulu : une pull request fusionnée ne peut pas, à elle seule, changer ce que le service exécute.

Mais le build, lui, exécute le dépôt. scripts/build.mjs et les dépendances de package-lock.json tournent sur le serveur à chaque push, sous le compte du service. Une pull request qui touche à scripts/, à package.json ou à package-lock.json se relit donc comme du code qui s'exécutera sur le serveur — pas comme une diapo.

rsync --delete épargne deux dossiers. error/ et stats/ appartiennent à ISPConfig et sont exclus de la synchronisation. Tout autre fichier déposé à la main dans le DocumentRoot est supprimé au déploiement suivant.

Le droit d'écriture tient à une ACL. Si ISPConfig réinitialise les droits du site, le déploiement échoue sur une erreur de permission : relancer installer.sh la repose.

Node.js ne se met pas à jour tout seul. Il est installé hors d'apt. Suivre les versions LTS sur https://nodejs.org/fr/about/previous-releases et changer NODE_VERSION de temps en temps.