Bienvenue sur ce nouveau wiki qui utilise hugo dans lequel je vais parler des découvertes que je fais autour du sujet ops. Mes articles seront toujours écrits en français car les ressources en anglais sont déjà très nombreuses. Dans cette première page, je vais justement expliquer comment je déploie ce wiki en utilisant hugo, docker et docker-compose.
On va commencer par le début, j’avais écris en php un moteur de blog qui était assez dégueulasse, tellement dégueulasse que je n’ai jamais osé le mettre sur github 😳 Ça faisait donc un moment que je regardais les générateurs de site statique pour le remplacer et mon choix s’est arrêté sur hugo car il semblait assez mâture et que j’avais envie d’apprendre le go. Ce wiki sera donc entièrement sous github et je vais expliquer ici les étapes pour passer du dev à la prod.
Mon idée de base avec un site entièrement statique était que je pouvais embarquer le site, une fois généré, dans une image docker nginx de base. C’est donc ce que j’ai fait en utilisant docker multi-stage afin de produire une image légère ne contenant que le code et l’image nginx. Voici à quoi ressemble le Dockerfile au global et on va prendre le temps de détailler un peu les différentes étapes pas à pas.
On commence par la première ligne :
FROM debian:stable-slim as build
Cela va nous permettre de faire un premier container nommé build dans lequel on va installer hugo et générer le site. On pourra l’utiliser dans notre image finale à l’aide du flag --from
de la commande COPY
.
Pour la suite, c’est assez classique :
ENV HUGO_VERSION X.XX.X
On définit une variable qui spécifie la version d’hugo.
ARG LOCAL=0
Ensuite, on définit l’argument LOCAL
qui sera utile pour le cas du développement et donc du build en local. On verra ça plus loin.
RUN apt-get update \
&& apt-get install -y \
wget \
&& rm -rf /var/lib/apt/lists/*
RUN wget -qO- -SL "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_Linux-64bit.tar.gz" \
| tar -xzC /bin \
&& rm -f /bin/README.md /bin/LICENSE
Il s’agit de l’installation d’hugo.
COPY ./www /www
WORKDIR /www
On copie les fichiers sources du site et on ajoute une directive WORKDIR
pour spécifier le dossier de base à utiliser dans ce container.
RUN if [[ $LOCAL -eq 1 ]]; then \
/bin/hugo --baseUrl=http://igln.fr/; \
else \
/bin/hugo --baseUrl=https://igln.fr/; \
fi
Là, on construit le site, le contenu sera donc dans /www/public/
. La condition sur la variable LOCAL
permet de spécifier l’option --baseUrl
qui sera https://igln.local si le site est en local. En prod, on sera sur https://igln.fr (le domaine sur lequel vous êtes actuellement).
FROM nginx:X.XX
LABEL version=X.X.X
On utilise une image nginx upstream et on ajoute un label contenant la version de l’image docker. Cela sera utilisé par la suite pour générer un tag sur l’image docker. Les fichiers générés par hugo sont dans le dossier /www/public
on va donc devoir les déplacer dans /var/www
qui sera configuré comme le root dans la configuration nginx :
COPY --from=build /www/public /var/www
On définit le COPY
depuis le container nommé build
. On a donc copié les fichiers produits dans le container précédent sans les sources et l’installation d’hugo.
Maintenant, on va voir comment on déploie cette image sur docker hub pour l’utiliser par la suite en production.
Pour déployer l’image sur docker hub, on va utiliser Github actions. Dans toutes mes images docker j’insère un LABEL avec la version. Ce label sera lu par les scripts de build et de push docker pour poser un tag sur docker hub. Cela me permet de versionner simplement, sans avoir besoin de poser de tags sur mon repository git.
Voici donc le fichier contenant le job pour construire et pousser mes images sur docker hub :
Le déclenchement de ce job ne se fait que sur la branche master lorsque des modifications ont été faîtes sur les fichiers dans le dossier docker
(dossier contenant toutes mes images docker). Le job se décompose en deux étapes qui sont gérées par deux scripts distincts :
docker-build.sh
:docker-push.sh
:On commence par cloner le dépôt :
git clone git@github.com:nierdz/igln.fr.git
On fait une nouvelle branche dans laquelle on écrit notre article en markdown :
git checkout -b feat/mon-super-article
vim docker/igln.fr/www/content/posts/mon-super-article.md
Pour tester l’article en local, il faut ajouter une entrée dans son /etc/hosts
qui fait pointer le nom de domaine vers 127.0.0.1
:
127.0.0.1 igln.local
Il faut ensuite construire l’image et lancer le container. Pour cela, il existe une target docker-run-igln-local dans le Makefile
qui va construire l’image en local, supprimer le précédent conteneur s’il en existait un et lancer le conteneur :
make docker-run-igln-local
Il ne reste plus qu’à aller voir le résultat sur son navigateur sur https://igln.local. Quand on modifie le contenu, il faut ensuite relancer la target make docker-run-igln-local :
make docker-run-igln-local
Une fois qu’on est satisfait de l’article, il ne reste plus qu’à modifier la version dans le Dockerfile, merger notre branche dans master et laisser github actions travailler à notre place.
Ce n’est néanmoins pas tout à fait fini car il faut ensuite utiliser cette image quelque part pour afficher notre wiki. Pour cela, j’utilise docker-compose pour la facilité et la souplesse de cet outil. Ce choix est motivé par le fait que ce site est hebergé sur un simple serveur et que si le service tombe, ce n’est absolument pas grave donc je n’ai pas besoin de mécanisme de redondance.
Voici donc le fichier docker-compose-igln.yml
qui permet de faire tourner l’image docker :