02 Guide pas-à-pas - Atelier 2

Dockerisez un CMS flat-file
avec contenu en volume

Le studio créatif livre du contenu PHP régulièrement. Vous emballez le moteur dans une image, et vous montez le contenu en volume pour qu'il soit modifiable sans rebuild. Six étapes guidées.

Ce qu'on vous fournit

Le dossier labos/semaine-1/demande-2-web-flat/ contient :

Vous y ajoutez : Dockerfile, .dockerignore, construire.sh, demarrer.sh, arreter.sh, votre README.md.

Avant de commencer

Pré-requis

Vue d'ensemble

Le parcours en six étapes

La grande idée nouvelle : séparer ce qui vit dans l'image (le moteur) de ce qui vit dans un volume (le contenu). Le studio créatif pourra ensuite mettre à jour le contenu sans toucher à votre image.

Étape 01

Inspecter moteur et contenu

Étape 02

Écrire le Dockerfile

Étape 03

Construire l'image

Étape 04

Démarrer avec volume monté

Étape 05

Démontrer la mise à jour à chaud

Étape 06

Encapsuler et finaliser

01

Inspecter le moteur et le contenu

Comprendre où vit chaque fichier dans la solution finale, et pourquoi cette séparation existe.

Indications

Ouvrez les fichiers dans votre éditeur :

  • moteur/index.php - liste les articles. Repérez la ligne qui cherche les fichiers : __DIR__ . '/fp-content/articles'. Cette ligne suppose que fp-content/ est au même niveau que index.php dans la hiérarchie servie par Apache.
  • moteur/article.php - affiche un article. Repérez basename(preg_replace(...)) : c'est une mesure de sécurité contre l'injection de chemin.
  • fp-content/articles/festival-oiseaux-migrateurs-2026.html - notez le bloc <!-- METADONNEES ... --> en tête. C'est le moteur qui le lit.

Pourquoi cette séparation ?

Si on mettait le contenu dans l'image, alors chaque ajout d'article au studio créatif demanderait un rebuild Docker. C'est lourd. En montant fp-content/ en volume, on peut éditer un fichier sur l'hôte et le voir apparaître dans le container immédiatement.

Vous pouvez expliquer en deux phrases pourquoi le moteur va dans l'image et le contenu dans un volume.
02

Écrire le Dockerfile

Créer le Dockerfile qui copie SEULEMENT le moteur dans l'image, et qui prépare l'environnement pour qu'Apache puisse exécuter du PHP.

Indications

  • Image de base : php:8.2-apache (PHP 8.2 avec Apache pré-configuré).
  • L'instruction RUN exécute une commande pendant le build. Les CMS flat-file utilisent souvent la réécriture d'URL : activez mod_rewrite avec a2enmod rewrite.
  • Apache sert /var/www/html/ par défaut (différent de /usr/local/apache2/htdocs/ de l'Atelier 1 qui utilisait httpd:alpine).
  • Vous pouvez créer le point de montage fp-content dans l'image avec un autre RUN et un mkdir -p, et donner les bons droits avec chown à www-data:www-data.

Squelette à compléter :

Dockerfile - squelette
FROM image-de-base

LABEL pavillon="evenements"

# Activer mod_rewrite (optionnel pour le moteur exemple,
# mais utile pour les CMS comme FlatPress)
RUN commande-pour-activer-mod-rewrite

# Copier seulement le moteur, pas le contenu
COPY source destination

# Préparer le point de montage du volume
RUN mkdir -p chemin && chown -R

EXPOSE 80
Si vous copiez le dossier fp-content/ dans l'image (par exemple avec COPY . /var/www/html/), vous mettez le contenu DANS l'image, ce qui annule l'intérêt du volume. Restreignez votre COPY au seul dossier moteur/. Et utilisez .dockerignore pour empêcher ça aussi.
Le Dockerfile contient au minimum un FROM, un RUN qui active mod_rewrite, un COPY qui ne touche QUE moteur/, un RUN qui crée fp-content/, et un EXPOSE.
03

Construire l'image

Lancer le build et obtenir une image taguée zoo-evenements:1.0 (ou un nom de votre choix, sémantique).

Indications

Comme dans l'Atelier 1 : docker build -t nom:version -t nom:latest .

Au build, vous verrez :

  • Le téléchargement de php:8.2-apache (plus lourd que httpd:alpine : autour de 400 Mo, c'est normal, PHP est inclus).
  • L'exécution du RUN a2enmod rewrite.
  • La copie du moteur.
docker images liste votre image. Sa taille est de l'ordre de 400 Mo (la plus grosse vient de PHP+Apache, votre contenu ne pèse rien).
04

Démarrer avec volume monté

C'est ici qu'arrive la nouveauté de l'Atelier 2. La commande docker run reçoit une option supplémentaire : -v pour monter un dossier de l'hôte dans le container.

Indications

  • Option -v cheminHote:cheminContainer monte le dossier hôte sur le chemin container. Utiliser un chemin absolu pour cheminHote (par exemple $(pwd)/fp-content).
  • Apache sert /var/www/html/. Le moteur s'attend à trouver fp-content/ au même niveau que ses fichiers PHP.
  • Suffixe :ro à la fin du -v rend le volume en lecture seule. C'est volontaire : le moteur ne doit pas pouvoir modifier les articles, seul le studio créatif sur l'hôte le fait.
Terminal
$ docker run -d --name "nom-container" \
    -p "8080:80" \
    -v "cheminHote:cheminContainer:ro" \
    nom-image

Ouvrez http://localhost:8080/ dans votre navigateur.

La page d'accueil affiche les 3 articles du studio créatif (Festival des oiseaux migrateurs, Journée des pollinisateurs, Nuit des musées). Cliquer sur un article ouvre la fiche complète.
Si la liste est vide ou si la page est blanche, le volume n'est probablement pas bien monté. docker exec -it nom-container ls /var/www/html/fp-content/articles doit afficher les 3 fichiers .html. Si non, vérifiez votre chemin absolu.
Sur Windows ou WSL, les chemins peuvent nécessiter une adaptation. $(pwd) en bash retourne le chemin Linux ; sous PowerShell, c'est ${PWD}. Sur certains systèmes, Docker exige un chemin de style Unix même sous Windows.
05

Démontrer la mise à jour à chaud

Prouver que le studio créatif peut publier un nouvel article sans toucher au container Docker.

Démarche

  1. Le container du Step 04 tourne, vous voyez les 3 articles.
  2. Sur l'hôte, créez un fichier fp-content/articles/test-mise-a-jour.html avec le bloc de métadonnées requis (TITRE, DATE, ECOSYSTEME) et un peu de contenu HTML.
  3. Rechargez la page d'accueil dans le navigateur (F5).

Modèle minimal de fichier :

fp-content/articles/test-mise-a-jour.html
<!-- METADONNEES
TITRE: Test de mise à jour
DATE: 2026-04-30
ECOSYSTEME: marin
-->

<p>Article créé sans rebuild Docker.</p>
Le 4ème article apparaît sur la page d'accueil immédiatement. Aucun docker build n'a été lancé.
Si vous oubliez le bloc METADONNEES, le moteur affichera l'article avec le titre "Sans titre" et sans date. Format strict : commentaire HTML ouvrant <!--, le mot METADONNEES en majuscules, puis chaque champ sur sa ligne (TITRE:, DATE:, ECOSYSTEME:), puis fermeture -->.
06

Encapsuler dans des scripts et finaliser

Comme à l'Atelier 1, trois scripts d'usage. Plus la documentation. Plus le .dockerignore qui devient critique ici.

Trois scripts

Mêmes principes qu'à l'Atelier 1 (kebab-case, exécutables, set -e, variables en tête, messages colorés). Différences pour cette demande :

  • demarrer.sh doit construire le chemin absolu vers fp-content/ et le passer en option -v. Vérifiez que le dossier existe avant de lancer.
  • arreter.sh ne doit PAS supprimer le contenu. Stop + remove du container, fin de l'histoire.

.dockerignore important pour cette demande

Vous voulez absolument que fp-content/ ne soit PAS embarqué dans l'image. Ajoutez-le explicitement à .dockerignore. Sinon, COPY moteur/ ne le copiera pas, mais le contexte de build l'enverra quand même au démon Docker, ce qui est gaspillé.

.dockerignore - extrait minimal
.git
*.log
*.tmp
construire.sh
demarrer.sh
arreter.sh
README.md
fp-content
.dockerignore

README.md

En plus des trois sections obligatoires (Ce que c'est, Comment lancer, Ce qu'on voit) :

  • Une section "Comment ajouter un article" qui montre le format des métadonnées.
  • Une section "Démontrer la persistance" qui guide la démonstration de l'étape 5.
Le séquence complète ./construire.sh ; ./demarrer.sh démarre le site avec les 3 articles. Vous démontrez l'ajout d'un 4ème article sans rebuild. ./arreter.sh stoppe le container, le contenu reste sur l'hôte.

Trois défis optionnels

Défi A - Vrai CMS flat-file

Remplacez le moteur exemple par un vrai CMS flat-file : FlatPress, Pico, Grav, HTMLy ou Bludit. Téléchargez-le, mettez-le dans moteur/, ajustez le Dockerfile (chemin de contenu, modules Apache requis). Démontrez qu'il fonctionne.

Défi B - Volume nommé Docker

Au lieu de monter un dossier hôte avec -v $(pwd)/fp-content:..., créez un volume nommé Docker (docker volume create) et utilisez-le. Quel est l'avantage ? Quel est l'inconvénient ?

Défi C - Sécurité

Inspectez votre image avec docker scan ou docker scout cves. Quelles vulnérabilités connues sont présentes ? Pourquoi ? Que feriez-vous en production pour les réduire ?