La plupart de nos sites hébergés sont rendus statiquement, construits avec des outils comme Hugo, Zola ou Jekyll. En général, tous ces générateurs de sites prennent une entrée simplifiée (généralement du Markdown) et génèrent du HTML bien défini en sortie. Cela laisse la question : comment puis-je héberger un tel site ?
Il existe des fournisseurs spécialisés offrant un hébergement pour les sites statiques, mais comme vous le savez, nous avons pris une autre voie en construisant notre infrastructure principale. Pour notre cloud, le dénominateur commun pour le déploiement est un conteneur. Et avec cela vient la question : comment passer d’une build de site statique à un conteneur qui héberge le site web ?
Commençons donc par générer une page très simple « hello world » avec Hugo.
hugo new site hello
cd hello
git init
git submodule add https://github.com/theNewDynamic/gohugo-theme-ananke.git themes/ananke
echo "theme = 'ananke'" >> hugo.toml
Pour vérifier la build, nous pouvons démarrer le serveur localement :
hugo serve
Puis notre propre page « Hello World » apparaît sur http://localhost:1313
Jusqu’ici tout va bien. Maintenant, envisageons de mettre cela dans un conteneur.
Techniquement, nous pouvons suivre deux voies différentes ici :
Pour rendre notre exemple plus reproductible et moins dépendant des environnements locaux, nous choisissons l’option 1 pour ce scénario. Cela rend aussi les pipelines CI/CD plus propres puisque l’environnement de build est entièrement défini dans le Dockerfile.
Une image de conteneur commence toujours par une image de base. Pour cela, nous utilisons Alpine Linux car elle est petite (environ 5 Mo) et fournit assez d’outils pour notre projet.
Nous allons utiliser un build multi-étapes, une technique supportée par les outils modernes de build de conteneurs qui permet d’utiliser une image pour la construction et une autre pour l’exécution. Cela garde notre image finale petite en excluant les outils de build non nécessaires à l’exécution.
Étape 1 : Build
FROM alpine AS build
RUN apk add --no-cache hugo
WORKDIR /src
ADD . .
RUN hugo --minify
Dans cette étape, nous :
--minify pour produire une sortie optimiséeLe site construit se retrouve dans /src/public/.
Étape 2 : Exécution
FROM alpine AS runner
RUN apk add --no-cache lighttpd
COPY --from=build /src/public /var/www/localhost/htdocs
EXPOSE 80
CMD ["lighttpd", "-D", "-f", "/etc/lighttpd/lighttpd.conf"]
Dans cette étape, nous :
-D)Voici le Dockerfile complet combinant les deux étapes :
# Stage 1: Build the static site
FROM alpine AS build
RUN apk add --no-cache hugo
WORKDIR /src
ADD . .
RUN hugo --minify
# Stage 2: Serve with lighttpd
FROM alpine AS runner
RUN apk add --no-cache lighttpd
COPY --from=build /src/public /var/www/localhost/htdocs
EXPOSE 80
CMD ["lighttpd", "-D", "-f", "/etc/lighttpd/lighttpd.conf"]
Enregistrez ceci sous le nom Dockerfile à la racine de votre projet Hugo.
Vous pouvez utiliser n’importe quel outil compatible OCI comme Podman ou Docker. Les exemples ci-dessous utilisent docker, mais podman fonctionne comme un remplacement direct.
Pour construire l’image :
docker build -t my-website .
Pour la lancer localement :
docker run -p 8080:80 --rm my-website
Votre site est maintenant accessible sur http://localhost:8080
L’option -p 8080:80 fait correspondre le port 8080 de votre machine au port 80 dans le conteneur. L’option --rm supprime automatiquement le conteneur à l’arrêt.
Cette configuration présente plusieurs avantages :
Taille d’image réduite : L’image finale contient uniquement Alpine (~5 Mo) + lighttpd (~1 Mo) + vos fichiers HTML. Pas de Node.js, pas de Ruby, pas d’outils de build qui alourdissent l’image de production.
Builds reproductibles : La même version exacte de Hugo tourne en CI comme localement, éliminant les problèmes de type « ça marche chez moi ».
Démarrage rapide : lighttpd démarre en millisecondes, parfait pour les déploiements scale-to-zero sur DTZ.
Sécurité : Le conteneur de production a une surface d’attaque minimale – juste un serveur de fichiers statiques sans runtime dynamique.
Si vous construisez votre image sur un Mac Apple Silicon (ARM64) ou une autre architecture non standard, rappelez-vous que les serveurs tournent typiquement sur AMD64 (x86_64). Pour garantir que votre conteneur fonctionne correctement sur DTZ (et la plupart des autres fournisseurs cloud), vous devriez spécifier explicitement la plateforme cible lors de la build.
Changez votre commande de build pour :
docker build --platform linux/amd64 -t my-website .
Cela indique à Docker de cross-compiler l’image pour les serveurs Linux standard, assurant la compatibilité quelle que soit la machine de build.
Une fois votre image construite, vous pouvez la pousser vers un registre de conteneurs et la déployer sur DTZ. Si vous utilisez notre registre de conteneurs :
# Tag pour le registre DTZ
docker tag my-website YOUR_CONTEXT_ID.cr.dtz.dev/my-website:latest
# Connexion et push
docker login YOUR_CONTEXT_ID.cr.dtz.dev -u apikey
docker push YOUR_CONTEXT_ID.cr.dtz.dev/my-website:latest
Ensuite, créez un service conteneur dans le tableau de bord DTZ pointant vers votre image. Le service gérera automatiquement les certificats TLS, la scalabilité et le routage.
Pour des déploiements automatisés à chaque commit, consultez notre GitHub Action pour des déploiements transparents.
Le même schéma fonctionne pour d’autres générateurs. Voici les changements clés :
Pour Zola :
FROM alpine AS build
RUN apk add --no-cache zola
WORKDIR /src
ADD . .
RUN zola build
Pour Jekyll :
FROM ruby:alpine AS build
RUN apk add --no-cache build-base
RUN gem install bundler jekyll
WORKDIR /src
ADD . .
RUN bundle install
RUN bundle exec jekyll build
L’étape runtime reste identique – il suffit de copier depuis /src/public (Zola) ou /src/_site (Jekyll) vers la racine des documents de lighttpd.
Conteneuriser des sites statiques est simple une fois que vous comprenez le modèle : construire dans une étape, servir dans une autre. Le résultat est un conteneur minuscule, rapide et sécurisé, parfait pour les déploiements cloud modernes.
Cette approche correspond bien à notre philosophie chez DTZ – usage minimal des ressources, démarrages à froid ultra rapides, et une infrastructure qui scale jusqu’à zéro quand elle n’est pas utilisée. Un site statique dans un conteneur d’environ 10 Mo qui démarre instantanément est sans doute la forme la plus efficace d’hébergement web.