Héberger un blog Hugo avec Docker

Contexte
Les manipulations décrites dans cet article sont faites sur un serveur dédié sous Debian Buster (10). Un serveur dédié ? Le gars est Cloud architect machin truc et son blog n’est même pas hébérgé sur Bucket S3 ou GCS. Oui cela peut surprendre mais j’aime toujours autant passer du temps perso a entrenir mon bon vieux serveur dédié sous Debian. Ca permet aussi de rester au coeur du métier d’administateur système qu’on a de plus en plus tendance à oublier. Je mettrai tout de même une CI/CD mais pour le moment on va rester “simple”.
Prérequis
- Installer Docker
- Installer Hugo Extended v0.78.2 (Il faudra probablement installer Go mais il était déjà présent sur ma machine)
Le setup
On va tout simplement avoir besoin d’un conteneur Traefik qui aura pour rôle d’être un reverse proxy capable de gérer automatiquement nos certificats SSL et d’un conteneur Nginx qui servira le contenu statique du blog.
Docker
Pour se faire, il suffit commencer par créer un network
Docker qu’on l’on appelera web
:
docker network create web
On vérifie ensuite que le network
a bien été créé :
docker network ls
Maintenant on passe a la création du fichier docker-compose.yml
:
version: '3'
services:
traefik:
image: traefik:1.7-alpine
container_name: traefik
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /opt/traefik/traefik.toml:/etc/traefik/traefik.toml
- /opt/traefik/acme.json:/acme.json
restart: always
networks:
- web
hugo_blog:
image: nginx:alpine
container_name: blog
volumes:
- /srv/blog/public/:/usr/share/nginx/html:ro
restart: always
networks:
- web
labels:
- "traefik.backend=blog.bracloud.services"
- "traefik.docker.network=web"
- "traefik.frontend.rule=Host:blog.bracloud.services"
- "traefik.enable=true"
- "traefik.port=80"
- "traefik.frontend.entryPoints=http,https"
networks:
web:
external: true
Traefik
Comme on peut le constater, on monte plusieurs fichier au sein de du conteneur traefik :
-
/var/run/docker.sock:/var/run/docker.sock
: Socket docker, utile à traefik pour écouter tout ce qu’il se passe au niveau de nos conteneurs qui tournent -
/opt/traefik/traefik.toml:/etc/traefik/traefik.toml
: Le fichier de configuration de traefik au formattoml
debug = false logLevel = "ERROR" defaultEntryPoints = ["https","http"] [entryPoints] [entryPoints.http] address = ":80" [entryPoints.http.redirect] entryPoint = "https" [entryPoints.https] address = ":443" [entryPoints.https.tls] [retry] [docker] endpoint = "unix:///var/run/docker.sock" watch = true exposedByDefault = false [acme] email = "your-email-here@my-awesome-app.org" storage = "acme.json" entryPoint = "https" onHostRule = true [acme.httpChallenge] entryPoint = "http"
J’utilise une ancienne version de traefik (v1.7). Je ne vais pas décrire toute la configuration ci-dessus mais vous pouvez en savoir plus sur le site officiel. Je vais quand même souligner une option qui me semble importante à modifier dans la section [docker] :
exposedByDefault
: Par défaut àtrue
, je pense qu’il est plus pertinent de selectionner les conteneurs que l’on souhaite exposer à travers Treafik via le label dockertraefik.enable=true
Pour résumer cette configuration :- Je fais le choix de rediriger systèmatiquement http vers https (section [entryPoints])
- Ecoute du backend docker pour savoir les conteneurs à ajouter ou non (oui il est aussi possible d’écouter d’autres backends pour ajouter dybnamiquement des conteneurs comme Amazon ECS ou bien Consul)
- Configuration de ACME avec le stockage des certs/keys dans le fichier acme.json et gestion des challenges en HTTP.
-
/opt/traefik/acme.json:/acme.json
: Le fichier où traefik stockera les certificats/keys délivrés par Let’s Encrypt. Il faudra créer ce fichier avec les bons droits :touch /opt/traefik/acme.json && \ chown root:root /opt/traefik/acme.json && \ chmod 600 /opt/traefik/acme.json
Nginx
Et enfin, Nginx ! Ce sera notre serveur web idéal, pour servir le contenu statique que l’on aura préalablement généré via le binaire hugo
:
hugo -D
Concernant le setup de ce conteneur, on ne fera rien d’exotique ci ce n’est de :
- Monter le dossier
public/
de notre blog Hugo dans le dossier/usr/share/nginx/html
du conteneur en read only pour plus de sécuritévolumes: - /srv/blog/public/:/usr/share/nginx/html:ro
- Mettre en place les labels docker utiles à Traefik :
labels: - "traefik.docker.network=web" # On spécifie le network docker dans lequel se situe le conteneur - "traefik.frontend.rule=Host:blog.bracloud.services" # Ce conteneur ne sera joignale que si l'en-tête http `Host` a la valeur blog.bracloud.services - "traefik.enable=true" # On active l'exposition du conteneur à Traefik - "traefik.port=80" # Port d'écoute de nginx au sein de conteneur
Lancement du blog
Le moment magique tant attendu. Il suffit tout simple le lancer le fichier docker-compose.yml
:
docker-compose -f docker-compose.yml -d
Et voilà notre blog est exposé en http/https avec un certificat SSL qui se renouvelera tout seul.