Comment déployer son site statique 11ty depuis Github vers alwaysdata
Utiliser un moteur de site statique c'est sympa, léger, économique mais la mise en ligne des dernières mises à jour finit souvent comme un processus manuel, parfois laborieux, souvent répétitif. Mais comme pour tout processus répétitif, on se sent mieux quand on automatise des choses.
La dernière fois je vous avais parlé de comment j'utilisais 11ty comme moteur et Obsidian comme éditeur de contenu mais j'avais occulté sur le processus de mise en ligne et il est temps d'y remédier.
Note
Par soucis de simplicité et parce que c'est ce que je connais le mieux, je vais décrire mon processus avec un repository Git hébergé sur Github et un hébergement du site chez alwaysdata mais le principe est a priori transposable dans des contextes différents.
Comme on avait vu la dernière fois ce blog est sur un repository Git et à chaque nouvelle mise à jour, je fais donc un commit
que je push
ensuite sur Github.
Maintenant il faut trouver un moyen de dire à Github que, dès qu'il reçoit une mise à jour, il lui faudra envoyer un message au serveur d'hébergement du site pour que ce dernier puisse récupérer ces mises à jours et les mettent en ligne.
Pour ce faire, il existe les webhooks.
Configuration d'un site pour diffuser vos pages statiques chez alwaysdata
Servir un site statique sur alwaysdata est sûrement ce qu'il y a de plus simple.
Rendez-vous sur l'admin d'alwaysdata dans la section Web > Sites
et cliquez sur le bouton "Ajouter un site", puis :
- Dans le champ adresse, mettez l'adresse URL à laquelle vous souhaitez que votre site apparaisse
- Dans le champ type, choisissez
Fichiers statiques
- Dans le champ répertoire de travail, mettez
dossierDeVotreSite/dossierDeBuild
Le dossierDeVotreSite
est le dossier dans lequel vous aurez cloné votre repository Git, donc par défaut le nom du projet sur Github.
Le dossierDeBuild
est déterminé par la façon dont vous avez configuré votre site 11ty, chez moi c'est _site
mais ça pourrait tout autant être dist
ou build
ou foobar
, etc. Vérifiez donc ça directement sur la config de votre projet.
Pour finir validez ça et laissons ça de côté pour passer à la suite.
Setup du webhook chez alwaysdata
Le webhook est un nouveau service qu'il vous faudra ajouter et activer vous même sur votre compte alwaysdata.
Pour ça, il vous faudra donc :
- Ajouter une library de gestion de webhooks comme adnanh/webhook
- Créer un site
webhook
sur votre compte alwaysdata
Installer la library
Connectez-vous en SSH sur votre compte alwaysdata pour créer un dossier webhook
et y installer la library :
$ mkdir webhook
$ wget -O- https://github.com/adnanh/webhook/releases/download/2.8.0/webhook-linux-amd64.tar.gz | tar -xz --strip-components=1 -C webhook
Créer un site webhook sur alwaysdata
Rendez-vous sur l'admin d'alwaysdata dans la section Web > Sites
et cliquez sur le bouton "Ajouter un site", puis :
- Dans le champ adresse, mettez
<votreNomDeCompte>.alwaysdata.net/webhook
- Dans le champ type, choisissez
Programme utilisateur
- Dans le champ commande, mettez-y la commande qui devra être exécuté
./webhook -port $PORT -hooks ./hooks.json -logfile webhook.log
- Dans le champ répertoire de travail, mettez
webhook
(ou le nom du dossier où vous avez installé la library webhook de l'étape d'avant) - Dans l'onglet SSL, Forcez le HTTPS si ce n'est pas déjà le cas
- Dans l'onglet Avancé, Excluez le chemin
On en a pas vraiment fini avec alwaysdata mais il nous faudra y revenir plus tard. Maintenant parlons de Github.
Setup de Github
Rendez-vous donc sur la page Github de votre projet, puis allez sur l'onglet "Settings", ensuite dans le menu de gauche, dans la section "Code and automation", allez sur "Webhooks" et enfin cliquez sur le bouton "Add Webhook".
À partir de là :
- Dans le champ Payload URL, mettez
https://<votreNomDeCompte>.alwaysdata.net/webhook/hooks/deploy
- Dans le champ Content type, choisissez
application/json
- Dans le champ Secret, tapez un mot de passe (et vous allez me faire le plaisir de le noter dans un gestionnaire de mots de passe, parce qu'on va s'en resservir très vite et que, si jamais un truc foire, vous n'ayez pas à tout refaire parce que vous ne vous souvenez plus de celui-là)
- Gardez le reste par défaut (sauf si vous souhaitez faire autre chose)
- Et Ajoutez ce webhook nouvellement configuré.
On pourrait naïvement croire que c'est fini mais non. À ce stade chaque nouveau push va en effet envoyer une requête au serveur alwaysdata mais côté serveur il n'y a rien qui permette d'authentifier la requête comme légitime, ni dise quoi faire une fois cette requête reçue.
Configuration du webhook sur alwaysdata
Authentification et configuration
Vous allez donc devoir créer un fichier hooks.json
de configuration. Pour ce faire, soit vous vous connectez en SSH sur le serveur et l'ajoutez à la main, soit vous créez ce fichier localement et l'envoyez sur le serveur par SFTP. Peu importe vraiment, ce qui compte c'est que ce fichier existe sur le serveur au final.
Dans mon cas, et comme stipulé dans la commande à exécuter de la configuration du site webhook
, je l'ai mis dans le dossier webhook
. Ce n'est pas obligatoire mais si vous faites différemment pensez à bien uniformiser ça partout.
Ce fichier json devra ressembler à ceci :
[
{
"id": "deploy",
"execute-command": "/home/votreNomDeCompte/webhook/deploy.sh",
"command-working-directory": "/home/votreNomDeCompte",
"trigger-signature-soft-failures": true,
"pass-arguments-to-command": [
{
"source": "payload",
"name": "repository.name"
},
{
"source": "payload",
"name": "repository.clone_url"
},
{
"source": "payload",
"name": "head_commit.id"
}
],
"trigger-rule": {
"and": [
{
"match": {
"type": "value",
"value": "refs/heads/main",
"parameter": {
"source": "payload",
"name": "ref"
}
}
},
{
"or": [
{
"match": {
"type": "payload-hmac-sha1",
"secret": "VotreSuperMotDePasseQueVousAvezNotéDansVotreGestionaire",
"parameter": {
"source": "header",
"name": "X-Hub-Signature"
}
}
}
]
}
]
}
}
]
À noter que :
- Pour la clé
id
, mettez donc ce que vous voulez mais je conseille de donner le même nom que le nom de votre fichier de commande ci-après - Pour la clé
execute-command
, choisissez le chemin et le nom de fichiersh
que vous souhaitez. Par soucis de simplicité je garde tout dans le dossierwebhook
mais ce n'est pas obligatoire. - Si votre branche principale n'est pas
main
maismaster
, pensez alors à changer"value": "refs/heads/main",
par"value": "refs/heads/master",
Et si vous avez plusieurs sites 11ty à déployer de la même façon, vous pourrez juste modifier la partie trigger-rule
et y ajouter une nouvelle authentification :
"or": [
{
"match": {
"type": "payload-hmac-sha1",
"secret": "MotDePasseDeMonSite1",
"parameter": {
"source": "header",
"name": "X-Hub-Signature"
}
}
},
{
"match": {
"type": "payload-hmac-sha1",
"secret": "MotDePasseDeMonSite2",
"parameter": {
"source": "header",
"name": "X-Hub-Signature"
}
}
}
]
Notez donc que la seule différence entre les deux entrées sera le secret
.
On a donc désormais l'authentification en place et la commande à éxécuter, sauf que si vous suivez bien ce fichier deploy.sh
n'existe pas (encore).
Configuration du déploiement
Que vous suiviez ma façon de faire en créant un fichier webhook/deploy.sh
ou que vous préfériez faire à votre sauce, faites dans tous les cas un nouveau fichier .sh dans lequel vous allez y écrire la ou les commandes à éxécuter quand un nouveau push à été notifié.
Dans le cas d'un site fait avec 11ty, je propose donc un simple script comme suit :
#!/bin/bash
NAME=$1
DEST_DIR=${HOME}/${NAME,,}
cd ${DEST_DIR}
git pull origin main --rebase
npm i && npm run build
Dans ce script on y récupère le nom du repository via NAME
qui dans mon cas s'avère être aussi le nom du dossier où mon site 11ty est cloné. Ce n'est pas obligatoire mais si comme moi vous vous retrouvez avec plusieurs sites 11ty de la sorte vous pourrez utiliser le même script de déploiement pour tous vos sites au lieu de le dupliquer, mais c'est à vous de voir.
Donc ce script va, depuis votre home, :
- Aller dans le dossier du projet
- Mettre à jour sa codebase en allant
pull --rebase
les modifications récentes - Faire un
npm i
pour installer les nouvelles dépendances le cas échéant - Faire un
npm run build
pour générer les changements opérés dans le dernierpush
et les publier
Pour finir il vous faudra donner les droits d'exécution à ce script alors connectez-vous en SSH sur le serveur alwaysdata et tapez chmod +x path/to/deploy.sh
.
Et voilà ! Normalement si tout s'est bien passé vous devriez pouvoir faire un petit test en faisant un push
de modifications mineures et voir ces changements apparaitre.
Troubleshooting
Si jamais dans les 2 minutes (et encore je suis large) vous ne voyez pas vos modifications en ligne il s'est probablement passé quelque chose d'imprévu.
Dans ce cas, je vous invite à aller lire les logs dans le fichier webhook/webhook.log
sur le serveur alwaysdata. Vous devriez y trouver une réponse assez rapidement. Je ne vais malheureusement pas trop pouvoir vous aider plus que ça étant donné la diversité des problèmes possibles que vous pourriez rencontrer.
J'espère en tout cas que tout ça vous sera utile. ❤️
@GoOz Merci pour cette précieuse ressource que je me mets sous le coude ! Au boulot on a automatisé le déploiement par Eleventy depuis gitlab sur notre propre infra serveur, ça donne un fonctionnement trop pratique. Reproduire cette automatisation vers alwaysdata pour du perso, ça vend du rêve.
@dje_renard mon plaisir
@GoOz oooh, j'ai raté ça, je suis grave en retard dans mes lectures de flux. Merci pour le ping. Je tente ASAP.
@GoOz j’ai pensé immédiatement à ce qu'il faut faire pour déployer plusieurs sites ainsi, et quand tu dis « si vous avez plusieurs sites 11ty à déployer », je vois exactement la même chose dans les deux blocks “match” du JSON, normal ?
On est d'accord qu'un seul hook peut servir à plusieurs sites ?
@GoOz derniers trucs pas écrit :
- où mettre le fichier hooks.json (même si c’est pas trop dur à deviner via la commande configurée)
- donner les droits d’exécution au deploy.sh (trouvé via les logs)
Mais du coup, ça maaaaarche ! ????
Merci !!! ????
Plus qu'à finaliser la migration de DNS…
@GoOz tu devrais au moins mettre MotDePasseDeMonSite2 au lieu de MotDePasseDeMonSite1 dans le second, du coup. ????