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

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 format toml

    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 docker traefik.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.

Benjamin Rabiller
Benjamin Rabiller
Cloud architect/DevOps engineer

Passionné et investi dans l’informatique

comments powered by Disqus

Related