Utiliser une image docker pour générer son blog Hugo en Asciidoc
On a vu précédemment comment créer un blog avec Hugo et Asciidoc. On va maintenant le faire mais en utilisant un conteneur Docker.
Pourquoi?
Pour générer notre site, il nous faut quelques outils:
-
Des gemmes ruby (Asciidoctor, Rouge)
-
Hugo
Ça ne fait peut être pas grand chose mais ces outils ont des dépendances et on se retrouve au final avec une multitude de paquets à installer.
Par ailleurs ces dépendances pourraient évoluer en nombre ou en version; que faire si ces versions sont incompatibles avec d’autres programmes installés sur le système?
En passant à docker on remplace les multiples dépendances qui existaient par le seul démon docker et on s’affranchit des éventuels problèmes de compatibilité.
Cela permet également d’avoir un environnement de développement prêt à l’utilisation. Le conteneur servira autant pour afficher une version locale du site web pour une prévisualisation rapide que pour générer les fichiers statiques à envoyer au site web.
Comment?
Je suppose que docker est déjà installé. Sinon la documentation de docker est parfaitement claire à ce sujet.
Création de l’image
Je me suis une nouvelle fois inspiré de l’article de René Gielen mais j’ai choisi une approche moins complexe:
-
J’ai préféré partir de l’image Ruby à laquelle j’ai ajouté la gemme
rouge
et le binaire de Hugo. -
Je n’ai pas installé certaines choses qui ne m’étaient pour l’instant pas utiles.
-
J’ai également changé l’entrypoint car je voulais être capable de lancer d’autres commandes que
hugo
à partir du conteneur (notammentasciidoctor
)
Voici comment procéder:
Dans un sous répertoire hugo-asciidoc-builder
, créer les fichiers suivants:
#!/bin/bash
set -e
exec "$@"
# Greatly inspired from https://rgielen.net/posts/2019/creating-a-dockerized-hugo-asciidoctor-toolchain/#_creating_a_hugoasciidoc_toolchain_image
FROM ruby:2.7
ARG HUGO_VERSION=0.64.1 (1)
RUN gem install asciidoctor rouge
ADD https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_Linux-64bit.tar.gz /tmp/hugo.tgz
RUN tar -xzf /tmp/hugo.tgz -C /usr/local/bin/ && rm /tmp/hugo.tgz
COPY ./docker-entrypoint.sh /
ENTRYPOINT [ "/docker-entrypoint.sh" ]
CMD [ "hugo", "--help" ]
1 | Penser à mettre à jour la version de Hugo. Je préfère fixer la version pour être sûr de reproduire le même résultat à chaque fois que je reconstruit mon image. |
Ensuite, toujours à partir du même répertoire, on construit l’image (ne pas oublier le point .
à la fin):
docker build -t hugo-asciidoc-builder .
On devrait maintenant avoir une image hugo-asciidoc-builder
disponible en lançant docker images
:
REPOSITORY TAG IMAGE ID CREATED SIZE
hugo-asciidoc-builder latest 01dc064eb95f 8 days ago 901MB
On voit que l’image est relativement grosse, on pourrait grandement améliorer ce point en se basant plutôt sur l’image ruby:2.7-alpine , la version ruby:2.7 étant elle basée sur Ubuntu.
|
Utilisation de l’image
On peut maintenant mettre l’image à l’oeuvre.
À partir de la racine du projet hugo:
docker run \
--rm \ (1)
-v $(pwd):/source \ (2)
-p 127.0.0.1:1313:1313 \ (3)
hugo-asciidoc-builder \
hugo serve -D -s /source --bind "0.0.0.0" (4)
1 | On veut que le conteneur soit supprimé à la sortie de la commande |
2 | On monte le répertoire courant dans un répertoire source à la racine du conteneur |
3 | Pour répliquer le comportement par défaut du mode serveur de hugo, on publie le port 1313 du conteneur sur le port 1313 de notre machine mais uniquement sur l’interface localhost .
Si on veut que le site soit accessible depuis d’autres machines du réseau, mettre plutôt -p 1313:1313 |
4 | Plusieur choses ici:
|
docker run \
--user $(id -u):$(id -g) \ (1)
--rm \
-v $(pwd):/source \
hugo-asciidoc-builder \
hugo -s /source -b https://mydomain.tld (2)
1 | On dit au conteneur d’utiliser un compte ayant les mêmes identifiants utilisateur et groupe que nous. Comme des fichiers vont être générés ils auront donc le bon propriétaire. Dans le cas contraire les fichiers créés appartiennent à root et nécessitent donc les droits administrateur pour être modifiés. |
2 | On passe à Hugo l’URL à laquelle notre site va être disponible, il en a besoin pour générer les liens sur certaines pages. Notez qu’on n’a plus besoin de publier de port ni de préciser d’interface d’écoute à Hugo puisqu’on ne lance pas le serveur. |
Il ne reste plus qu’à transférer le contenu du répertoire public
à la racine de notre serveur web.
Docker compose
OK, on peut maintenant faire tout ce qu’on faisait avant mais sans avoir installé quoi que soit d’autre que docker sur notre système. Mais c’est un peu lourd d’avoir à taper une commande avec de multiples options à chaque fois.
On va donc créer deux petits scripts:
#!/bin/bash
docker run \
--rm \
-v $(pwd):/source \
-p 127.0.0.1:1313:1313 \
hugo-asciidoc-builder \
hugo serve -D -s /source --bind "0.0.0.0"
#!/bin/bash
docker run \
--user $(id -u):$(id -g) \
--rm \
-v $(pwd):/source \
hugo-asciidoc-builder \
hugo -s /source -b https://mydomain.tld
On rend les scripts exécutables chmod +x lancer-serveur-web.sh generer-le-site.sh
et on peut:
-
./lancer-serveur-web.sh
-
./generer-le-site.sh
En temps normal j’opterais pour docker-compose mais tant qu’on reste sur un conteneur ça suffit largement, ça évite d’ajouter une autre dépendance.
Bon allez puisqu’on y est, la version avec docker-compose:
-
Créer un fichier
docker-compose.yml
--- version: '3' services: hugo-asciidoc-builder: build: hugo-asciidoc-builder working_dir: /source command: hugo serve -D --disableFastRender --bind "0.0.0.0" (1) ports: - "127.0.0.1:1313:1313" volumes: - ".:/source"
1 J’ai ajouté l’option --disableFastRender
pour être sûr que le site se régénère entièrement à chaque changement. Pour l’instant je n’ai pas beaucoup de contenu donc ça ne me coûte pas grand chose, ça changera sûrement plus tard.
A noter que je ne modifie plus les UID et GID de l’utilisateur, pour le mode serveur ça ne sert pas car aucun fichier n’est écrit dans le répertoire courant.
Pour lancer le serveur: docker-compose up