La méthode
des baby steps
Développer un Dockerfile petit pas par petit pas - comme un vrai développeur, avec des échafaudages qui apparaissent puis disparaissent.
docker.projet.autos - le site compagnon Docker
Le Dockerfile final est un mensonge
Tous les tutoriels du monde montrent le Dockerfile final : cinq lignes propres, parfaites, dans le bon ordre. Ce fichier est un mensonge. Personne ne l'a écrit comme ça, de haut en bas, du premier coup.
Un vrai développeur avance par petits pas : une micro-modification, une vérification, puis la suivante. Il ajoute des lignes de test, les regarde travailler, puis les efface quand elles ont fini leur travail. Le fichier final ne garde aucune trace de ce chemin - mais ton historique de versions, lui, doit le raconter.
La boucle du baby step
Un baby step, c'est toujours la même boucle, répétée jusqu'à la victoire :
docker build - le cache rend ça presque instantané.docker run --rm pour voir le résultat.$ git commit -m "exploration : ls de la racine de l'image"
L'objectif du jour
On va dockeriser un mini serveur web qui affiche le menu du jour de la cafétéria. Une image nommée menu, un port publié, une page menu.html servie au navigateur.
Le Dockerfile final fera 5 lignes. Mais on va y arriver en 12 baby steps - avec des détours volontaires, des lignes de test, et deux grands effacements. C'est le chemin qui t'apprend Docker, pas la destination.
Un socle qui roule
Premier pas : la plus petite image possible qui fait quelque chose de visible. Pas le serveur. Pas le menu. Juste un témoin qui prouve que la chaîne build-run fonctionne.
$ cd menu-du-jour
$ git init
$ nano Dockerfile
FROM alpine CMD echo "le socle roule"
$ docker run --rm menu
Ce CMD echo est déjà un échafaudage : il ne survivra pas jusqu'à la fin. Son seul travail est de prouver que tout roule.
Regarder dans l'image avec ls
ls d'exploration : quand tu te demandes ce qu'il y a dans l'image, tu ne devines pas - tu regardes.Qu'est-ce qu'il y a réellement dans cette image alpine ? Le conteneur n'est pas ta machine : il a son propre système de fichiers. On remplace le témoin par un coup d'oeil :
FROM alpine CMD ls -la /
Voilà le monde intérieur de l'image. Changer un CMD ne coûte presque rien : tout le reste vient du cache, le rebuild prend une seconde.
Se placer avec WORKDIR, vérifier avec pwd
Notre application vivra dans /app. On ajoute un WORKDIR... et remarque bien : on insère la ligne au milieu du fichier, pas à la fin. L'ordre d'écriture n'est déjà plus l'ordre des lignes.
FROM alpine WORKDIR /app CMD pwd
Le dossier a été créé et on s'y trouve. Deuxième micro-vérification : CMD ls -la montre un dossier vide (juste . et ..). Deux petits pas valent mieux qu'un grand.
Apporter le menu, vérifier avec ls
Côté hôte, on crée la page du menu :
<h1>Le menu du jour</h1> <p>Poutine du chef</p> <p>Tarte au sucre</p>
Puis on l'embarque dans l'image, et on vérifie tout de suite avec le réflexe de l'étape 2 :
FROM alpine WORKDIR /app COPY menu.html . CMD ls -la
Le fichier est là, avec sa taille. Après chaque COPY, un ls. C'est le réflexe qui économise des heures de débogage.
Vérifier le contenu avec cat
cat de contrôle : ls prouve que le fichier existe, cat prouve que son contenu est le bon.Un fichier peut exister mais être vide, tronqué, ou être la mauvaise version. Un petit pas de plus :
FROM alpine WORKDIR /app COPY menu.html . CMD ls -la CMD cat menu.html
C'est exactement la technique de la diapo « un fichier dans l'image » du parcours : un CMD cat temporaire pour prouver que le COPY a bien fait son travail.
Des jalons dans le build avec echo
echo variés : des messages différents avant et après chaque sous-étape, pour savoir où le build en est rendu.Il est temps d'installer le serveur web. Une installation, ça peut échouer à moitié - alors on l'encadre de jalons :
FROM alpine WORKDIR /app COPY menu.html . RUN echo "=== jalon 1 : avant installation ===" && \ apk add --no-cache busybox-extras && \ echo "=== jalon 2 : installation terminee ===" CMD cat menu.html
# --progress=plain force Docker a montrer chaque ligne de sortie du build
Le jalon qui disparaît = le cache
Relance le même build, sans rien changer :
Les jalons n'apparaissent plus. Ce n'est pas un bogue : la couche vient du cache, Docker n'a rien réexécuté. Un jalon disparu, c'est une étape déjà faite.
Le serveur est-il vraiment là ?
L'installation dit qu'elle a réussi. On ne la croit pas sur parole - on vérifie, avec un cousin du ls :
CMD cat menu.html CMD which httpd
ls, cat, pwd, which : c'est la même famille. Des petites commandes jetables qui répondent chacune à une seule question - le fichier est-il là, le contenu est-il bon, où suis-je, l'outil est-il installé.
Le grand ménage : la vraie commande
Tout est vérifié : le fichier est là, le contenu est bon, le serveur est installé. Les échafaudages peuvent tomber, la vraie commande prend leur place :
FROM alpine WORKDIR /app COPY menu.html . RUN echo "=== jalon 1 : avant installation ===" && \ RUN apk add --no-cache busybox-extras CMD which httpd CMD httpd -f -v -h /app
httpd -f -v -h /app : le serveur web de busybox, en avant-plan (-f), bavard (-v), qui sert le dossier /app.
Lancer SANS -d : le mode développement
-d. On veut les logs sous les yeux, en direct.Le terminal semble gelé... c'est parfait ! Le serveur tourne en avant-plan et attend des visites. Dans un deuxième terminal (ou un navigateur) :
Et dans le premier terminal, la ligne de log tombe en direct :
Ctrl+C arrête le serveur, --rm fait le ménage du conteneur. Modifier, relancer, observer : la boucle reste courte.
Quand c'est stable : -d et docker logs
Le serveur est fiable, on ne veut plus le regarder en permanence. On le détache :
$ docker logs --follow menu-en-service # les logs restent accessibles a la demande
$ docker stop menu-en-service
- Le terminal est occupé par le serveur : voulu
- Logs en direct, sous les yeux
--rm: le conteneur s'efface tout seulCtrl+Cpour arrêter et repartir
- La main revient tout de suite
--namepour le retrouverdocker logspour consulter à la demandedocker stoppour arrêter proprement
Remarque : -d n'est pas une ligne du Dockerfile, c'est un choix de lancement. Rien à committer ici - le fichier n'a pas bougé.
Dernier baby step : réordonner pour le cache
Un détail agace : chaque fois qu'on modifie menu.html, le build refait l'installation. Normal - le COPY est avant le RUN, et une couche modifiée invalide toutes celles qui suivent. On remonte l'installation :
FROM alpine RUN apk add --no-cache busybox-extras WORKDIR /app COPY menu.html . RUN apk add --no-cache busybox-extras CMD httpd -f -v -h /app
Maintenant, changer le menu ne réinstalle plus rien : le build est instantané. Et savoure l'ironie : la deuxième ligne du fichier final est arrivée au douzième baby step. L'ordre du fichier n'a jamais été l'ordre du développement.
Ton historique raconte ton histoire
FROM alpine RUN apk add --no-cache busybox-extras WORKDIR /app COPY menu.html . CMD httpd -f -v -h /app
a9f3c21 remontee de l'installation avant le COPY (cache)
8d17e40 retrait des lignes de test, vraie commande httpd
5b02c9d verification : httpd est bien installe
e64a1f7 installation busybox-extras avec jalons
c3d98b2 cat de controle du contenu du menu
7f45a06 COPY menu.html + ls de controle
2b8ce13 WORKDIR /app + pwd temoin
91d604f exploration : ls de la racine de l'image
4a7b5e9 socle alpine + echo temoin
Le fichier final ne dit rien du chemin. L'historique dit tout : les explorations, les vérifications, les échafaudages montés puis démontés.
ls qui apparaissent et disparaissent ? Un vrai développement - et les points qui viennent avec.La boîte à échafaudages
Pour aller plus loin
La méthode des baby steps n'est pas une méthode « pour débutants ». C'est la méthode des développeurs qui livrent - un petit pas vérifié vaut mieux que dix grands pas espérés.