Aperçu



Lors de la construction d'images Docker, il arrive souvent que la taille augmente de manière inattendue. La plupart du temps, cela est dû à la création de couches inutiles. Cet article partage mon expérience d'optimisation pour alléger effectivement les images en utilisant la commande docker history afin de vérifier l'« arbre généalogique » des images.

En utilisant cette commande, vous pouvez identifier précisément ce qui alourdit vos images et créer des images plus efficaces.


docker history : Vérification de l'arbre généalogique des images

docker history est une commande qui montre comment une image spécifique a été construite et son historique de composition. Vous pouvez voir quelles couches sont empilées par chaque commande dans le Dockerfile, ainsi que le moment où chaque couche a été créée et sa taille.

Son utilisation est très simple.

docker history [options] <nom de l'image:tag>

Par exemple, pour vérifier l'historique de l'image my-app:latest sur votre machine locale, vous pouvez exécuter la commande suivante :

docker history my-app:latest

Les résultats affichent les couches de l'image en commençant par la plus récente jusqu'à l'image de base (la plus ancienne).

IMAGE          CREATED         CREATED BY                                      SIZE
a6215f271958   5 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B
<missing>      7 weeks ago     /bin/sh -c #(nop) ADD file:f28242cf608f6...   7.81MB
  • CREATED BY : La commande du Dockerfile qui a créé cette couche

  • SIZE : La taille occupée par la couche

Conseil utile : Afficher toute la commande avec --no-trunc

Par défaut, la sortie de docker history peut tronquer les commandes dans la colonne CREATED BY si elles sont trop longues. En utilisant l'option --no-trunc, vous pouvez voir l'intégralité de la commande, ce qui est essentiel pour une analyse précise.

docker history --no-trunc my-app:latest

Pourquoi l'analyse des couches est-elle importante : expérience d'optimisation réelle



La règle de base pour les images Docker est de créer une couche pour chaque commande dans le Dockerfile. Chaque couche représente un 'changement' par rapport à la couche précédente.

Le problème, c'est qu'une division inutile des couches peut entraîner une augmentation rapide de la taille de l'image.

Exemple : piège de COPY et RUN chown

Lors de la rédaction d'un Dockerfile, il est fréquent de copier les fichiers du projet dans le conteneur (COPY), puis de modifier la propriété de ces fichiers à un utilisateur spécifique (par exemple, appuser) en utilisant RUN chown.

Méthode inefficace : 2 couches

J'ai d'abord rédigé le Dockerfile de la manière suivante :

# 1. Copier les fichiers (copiés en tant que root)
COPY . .

# 2. Changer la propriété (exécuté comme une commande séparée)
RUN chown -R appuser:appgroup /app

En vérifiant l'historique de l'image construite avec docker history, j'ai constaté que deux couches avaient été créées.

IMAGE          CREATED BY                                        SIZE
<layer_id_2>   /bin/sh -c chown -R appuser:appgroup /app        150MB  <-- (problème !)
<layer_id_1>   /bin/sh -c #(nop) COPY dir:abc in /app           150MB

Un problème sérieux se pose ici.

  1. La commande COPY . . a ajouté des fichiers de 150MB à la couche 1.

  2. La commande RUN chown a copié les fichiers de 150MB de la couche 1 puis n'a changé que les informations de propriété, enregistrant à nouveau dans la couche 2.

Bien que le contenu des fichiers soit le même, l'un est enregistré sous root et l'autre sous appuser dans des couches différentes. Au final, ces deux couches rendent l'image totale de 300MB (150MB + 150MB).

Méthode efficace : 1 couche

Ce problème peut être facilement résolu en utilisant le drapeau --chown avec la commande COPY.

# 1. Copier et spécifier en même temps la propriété
COPY --chown=appuser:appgroup . .

Après avoir modifié le Dockerfile de cette manière, j'ai encore vérifié avec docker history :

IMAGE          CREATED BY                                             SIZE
<layer_id_1>   /bin/sh -c #(nop) COPY --chown=appuser... dir:abc     150MB

Une seule couche a été créée, et la taille totale de l'image a été réduite à 150MB. En combinant simplement deux lignes de commande en une, la taille de l'image a presque été réduite de moitié.


Conclusion

docker history est plus qu'un simple outil pour voir l'historique de création d'une image, c'est un outil d'analyse essentiel pour l'optimisation des images.

Après avoir modifié le Dockerfile, il est bon de se habituer à exécuter docker history --no-trunc pour vérifier si les couches ont été créées comme prévu et qu'il n'y a pas de couches qui occupent de l'espace inutile. Cette petite habitude contribue à créer des images légères et efficaces.