Une image docker représente plusieurs couches (layers).
Chaque layer est une instruction.
FROM ubuntu
RUN dd if=/dev/zero of=/root/file1.txt bs=1M count=100
RUN dd if=/dev/zero of=/root/file2.txt bs=1M count=100
RUN rm -f /root/file1.txt
RUN rm -f /root/file2.txt
En détaillant le dockerfile ci-dessus :
En faisant le build en détail :
docker build -t test-layers .
docker image history test-layers
IMAGE CREATED CREATED BY SIZE COMMENT
2031d313a146 42 seconds ago /bin/sh -c rm -f /root/file2.txt 0B
4a6f11abe452 42 seconds ago /bin/sh -c rm -f /root/file1.txt 0B
a7e2fbf34909 43 seconds ago /bin/sh -c dd if=/dev/zero of=/root/file2.tx… 105MB
53e59aa5f939 45 seconds ago /bin/sh -c dd if=/dev/zero of=/root/file1.tx… 105MB
7e0aa2d69a15 6 days ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 6 days ago /bin/sh -c mkdir -p /run/systemd && echo 'do… 7B
<missing> 6 days ago /bin/sh -c [ -z "$(apt-get indextargets)" ] 0B
<missing> 6 days ago /bin/sh -c set -xe && echo '#!/bin/sh' > /… 811B
<missing> 6 days ago /bin/sh -c #(nop) ADD file:5c44a80f547b7d68b… 72.7MB
Il faut lire les couches de bas vers le haut. Les premères couches font partis de l'image Ubuntu.
A partir de la 6eme couche, on voit nos commandes : 2x 105MB puis 2x 0B.
Si on regarde la taille de l'image :
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
test-layers latest 2031d313a146 2 minutes ago 282MB
282MB... Nous venons pourtant de supprimer les 2 fichier (file1 et file2) qui pesaient à eux seul 200MB...
En effet ! Docker fonctionne par système de couche. C'est à dire qu'une fois l'instruction passée, la taille et le layer seront non modifiables même si on fait une commande rm
derrière !
Pour réduire la taille de l’image il faut mettre l’instruction rm
au sur le même layer que la création du fichier !
Soit :
FROM ubuntu
RUN dd if=/dev/zero of=/root/file1.txt bs=1M count=100 && rm -f /root/file1.txt && dd if=/dev/zero of=/root/file2.txt bs=1M count=100 && rm -f /root/file2.txt
En refaisant le build :
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
test-layers latest a2ad2dd0ee8b 10 seconds ago 72.7MB
Dans cet exemple, 4 couches ont été réduites en 1 seule. L'image ne pèse plus que 72.7MB.
Un dockerfile doit donc se faire sur le moins de couches possible et les fichiers inutiles doivent être supprimés.