IGLN

đŸ’© mon petit merdier sur l’internet đŸ’©

Nouveau blog avec hugo

Bienvenue sur ce nouveau blog qui utilise hugo dans lequel je vais parler des dĂ©couvertes que je fais autour du sujet devops. Mes articles seront toujours Ă©crits en français car les ressources en anglais sont dĂ©jĂ  trĂšs nombreuses. J’espĂšre que je serai un peu plus productif que sur mon ancien blog… D’ailleurs, une sĂ©lection totalement arbitraire d’articles sera rĂ©intĂ©grĂ©e sur ce nouveau blog avec une rĂ©Ă©criture si besoin. Dans ce premier article, je vais justement expliquer comment je dĂ©ploie ce blog en utilisant hugo, docker et docker-compose.

Introduction

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 blog sera donc entiĂšrement sous github et je vais expliquer ici les Ă©tapes pour passer du dĂ©veloppement Ă  la production.

Docker

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.

DĂ©ploiement sur docker hub

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 :

  1. Étape de build gĂ©rĂ©e par le script docker-build.sh :
  1. Étape de push gĂ©rĂ©e par le script docker-push.sh :

Workflow : de l’Ă©criture d’un article jusqu’Ă  la prod

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 blog. 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 :