Introduction

Peut-être serez-vous surpris d’apprendre que la publication d’un article sur ce blog revient simplement à écrire du texte dans un fichier et envoyer un commit sur un dépôt Git. Ni plus, ni moins.

C’est là que commence toute une chaîne de publication afin de mettre à disposition le fameux article sur le Web ! Pour cela j’ai utilisé très peu d’outils et un peu d’imagination.

Le but du présent article est de vous présenter l’outil de la chaîne que j’ai dû développer pour mener à bien ce projet : Gachette. Puis de vous décrire comment le mettre en place.

Mais avant tout commençons à planter le décor !

Phénomène de goutte qui remonte après être tombé dans l’eau

Photo trouvée sur le profil de Nikk sur Flickr sous licence CC BY 2.0.

Plantons le décor avec l’Histoire logicielle de ce blog

(je comprendrais que ce chapitre ne soit pas très enthousiasmant pour vous, si c’est le cas, passez au suivant 😉)

En 2016 je vous parlais d’Hugo, le moteur de blog statique que j’utilise pour « confectionner » ce blog. Outil très intéressant qui utilise de simples fichiers pour générer un site web entier, statique ; c’est à dire en pur HTML et ne demandant aucune autre ressource finale qu’un serveur Web tel qu’Apache2, nginx, lighttpd, Caddy Server et j’en passe… Dans ma situation, le serveur Web en question est Nginx depuis 2013 environ - mais qu’importe.

Afin de garder en mémoire les travaux effectués, je vous partageais en 2017 l’outil Gitea, service Git sans prise de tête issu de Gogs.

À cette époque (entre 2016 et 2019/2020), pour publier mon blog il me faut :

  • (manuel) écrire l’article dans un fichier texte
  • (manuel) (facultatif) l’enregistrer sous Git avec un commit
  • (manuel) (facultatif) envoyer l’article sur Gitea
  • (manuel) compiler le site à l’aide de la commande hugo
  • (manuel) synchroniser les fichiers résultants sur mon serveur doté de Nginx, par exemple avec une commande rsync simple

À force de traîner à FOSDEM en 2016 et en 2017, j’ai non seulement appris que l’informatique sert à automatiser des tâches mais qu’il est aussi possible de le faire de manière « simple ».

Je me renseigne et j’apprends que sous Gitlab, Github et Gitea (plateformes que j’utilise à l’époque), il existe un système de webhooks. Qu’est-ce à dire ? Grossomodo je peux configurer ces plateformes pour qu’à chaque envoi de mon travail peut résulter un appel à une adresse Web.

Il suffit ensuite, à l’adresse appelée, de pouvoir étudier la requête envoyée et d’agir en conséquence (par exemple déployer un site).

Sur le papier ça a l’air fun :

  • (manuel) j’écris mon article dans un fichier texte
  • (manuel) je commite et pousse sur Gitea/Github/Gitlab
  • (automatique) la plateforme de réception envoie un appel à un de mes serveurs
  • (automatique) un de mes serveurs reçevant l’appel lance un script ou une action pour publier les dernières nouveautés

Parfait on se lance là dedans !

La naissance de Gachette

En 2019 où j’étudiais la question, je ne trouvais pas de serveur simple et léger qui puisse supporter les appels envoyés par Github, Gitlab et Gitea. Hors de question d’avoir 3 serveurs de webhooks différents sur mes machines.

Comme j’ai cru comprendre être ingénieur logiciel au travail 🤣, je me suis dit pouvoir l’être aussi à la maison sur mon temps personnel. À l’époque je m’amusais un peu avec le langage Crystal avec des amis, c’était l’occasion.

C’est ainsi qu’est né Gachette, un serveur de webhooks sous Licence MIT en Crystal (une syntaxe comme Ruby, mais compilé) qui supporte les plateformes Github, Gitlab et Gitea.

Sous ce langage, il existe quelques frameworks, dont Kemal, un framework web minimaliste qui permet d’ouvrir quelques routes très facilement. C’est ce que j’ai utilisé pour créer la première version 0.1 de Gachette en 2019.

À tout casser on doit être à 100 lignes de code. Bref. À aujourd’hui, plutôt 200+ lignes de code Crystal.

Voyons les particularités de mise en place de Gachette.

Mise en place de Gachette sur un serveur

Je ne vais pas reproduire ce que le fichier README de Gachette énonce si bien pour l’installation, cependant je peux vous faire un résumé rapide de l’installation/configuration :

# On récupère le projet
git clone https://github.com/blankoworld/gachette.git
cd gachette
# Pré-requis : Crystal, Shards et make doivent être installés
shards install
# On compile le logiciel
make

À l’issue de ces commandes devrait apparaître un fichier bin/gachette qui est un exécutable utilisable tel quel.

On le place où on veut, par exemple dans /srv/www/gachette/gachette puis on édite le fichier /etc/systemd/system/gachette.service dont le contenu est le suivant :

[Unit]
Description=Gachette webhooks service
After=network.target

[Service]
Type=simple
User=http
WorkingDirectory=/srv/www/gachette
ExecStart=/srv/www/gachette/gachette -c /etc/gachette.ini -b 0.0.0.0 -p 3000
Environment="KEMAL_ENV=production"
Restart=always

[Install]
WantedBy=multi-user.target

À noter qu’il faut adapter User=http par l’utilisateur de votre système d’exploitation, par exemple sous Debian c’est User=www-data. Mais également le port utilisé, ici c’est le port 3000.

Ensuite créez le fichier /etc/gachette.ini avec un contenu qui va décrire les dépôts/projets qui vont contacter le serveur webhooks et déclencher une action. Imaginons que le projet Gachette, sur Github, à l’adresse https://github.com/blankoworld/gachette veuille qu’à chaque commit nous exécutions le contenu du script /srv/www/gachette/deploiement.sh, nous allons écrire :

# contenu du fichier /etc/gachette.ini
[Un_nom_au_hasard]
service = github
namespace = blankoworld/gachette
key = monMot2Passe
scriptfile = /srv/www/gachette/deploiement.sh

Une fois la configuration faite, le service installé, vous pouvez faire en tant qu’utilisateur root :

# pour lancer le service
systemctl start gachette.service
# pour voir l'état du service
systemctl status gachette.service
# pour lancer le service à chaque redémarrage : 
systemctl enable gachette.service
# pour suivre ce qu'il se passe dans Gachette : 
journalctl -xe -f -u gachette.service

Tout résidera ensuite dans votre capacité à créer des scripts qui feront le travail de déploiement.

Dans ma situation, pour le présent blog, j’ai un script qui :

  • récupère la dernière version du dépôt Git du blog
  • compile le site pour générer les fichiers statiques
  • synchronise le résultat - si réussi - vers un dossier particulier
  • relance le serveur Web avec les nouveaux fichiers

Suite à mon dernier article sur Træfik pour publier ses conteneurs Docker, je me suis même essayé à l’utilisation de conteneurs Docker pour isoler les environnements, voire même à avoir des images Docker communes pour l’ensemble des sites Web statiques : très pratique !

On s’amuse bien par ici en somme 😉.

Conclusion

Bien que certains jugerons ma chaîne de publication assez alambiquée, utilisant des outils peu communs, voire pas du tout utilisés (Gachette notamment), ce système a déjà fait ses preuves et tourne bien : moins d’une minute après avoir enregistré un article, il est publié sur le web sans action humaine.

Il n’y a pour cela que 3 outils simples :

  • Gitea comme dépôt Git ; qui déclenche une demande auprès d’un serveur distant (ici Gachette)
  • Gachette qui reçoit la demande et lance un script de compilation/déploiement/traitement (bref, une action est menée)
  • Nginx comme serveur Web pour diffuser les pages statiques ainsi générées

L’utilisation de Docker en sus améliore le côté réutilisable des outils : pour plusieurs sites statiques j’utilise la même image qui va compiler les fichiers puis les mettre à disposition sur le net.

La difficulté réside cependant à notre capacité à créer des scripts pour lancer les différentes actions sur le serveur. La ligne de commande et Bash sont de fidèles alliés !

Liens utiles