Optimiser la taille des images Docker

Utiliser des une images plus petite offre des avantages tels que des temps d’importation et de téléchargement plus courts. Cela peut permettre de raccourcir les temps d’exécution de vos CI ou du démarrage de vos pods Kubernetes. Donc voici quelques conseils pour y parvenir : .

1. Éviter d’installer des outils inutiles

Pour protéger vos applications contre le piratage, n’installez pas d’outil inutile. Par exemple n’allez pas installer netcat qui permet de créer un tunnel TCP, même si certains de ces outils pourraient être utiles pour déboguer vos applications.

2. Utiliser les images officielles alpine

Le principal avantage en utilisant des images à base de distribution Alpine est leur taille. Regardez le tableau suivant :

DISTRIBUTION / VERSION / TAILLE /
Debian Jessie 123MB
Centos 7 193MB
Ubuntu 16.04 118MB
Alpine 3.6 3.98MB

Autre avantages:

  • l’installation des packages alpine est bien plus rapide.
  • compte tenu de la taille mini peu de paquets installés et donc plus sécurisé car contenant moins de failles possibles

3. Utiliser le plus souvent possible le multi stage

Le multi-stage est une fonctionnalité intéressante introduite avec la version 17.05 de Docker. Il est possible de décrire plusieurs étapes dans un même fichier Dockerfile, Chaque stage commençant par une commande FROM. Je vous conseille de nommer chaque stage en ajoutant AS , cela permet d’y faire référence dans un autre stage. Il est possible de copier une partie du système de fichier d’un stage avec la commande COPY en utilisant le paramètre –from=. La première application possible est de construire l’image en trois stages :

  • Le premier décris la partie commune des deux autres
  • Le second permet de construire votre application
  • Le troisième permet de ne copier que le résultat de la construction du second. Par exemple pour les images python utilisant pip, qui consomme énormément de place lors de la compilation des packages, il est possible de garder le résultat de la compilation en utilisant un environnement virtuel.

Un exemple : Création d’un image Ansible :

Non optimisée

FROM alpine:3.10.2

RUN apk update && apk upgrade
RUN apk add --no-cache python3 openssl
RUN apk add --no-cache --virtual .build-deps python3-dev gcc ca-certificates libffi-dev openssl-dev build-base
RUN pip3 install --no-cache-dir --upgrade pip ansible
RUN apk del .build-deps

docker images
REPOSITORY                              TAG                 IMAGE ID            CREATED             SIZE
ansible                                 0.1                 5e43ab54b9a0        56 seconds ago      393MB

Optimisée

FROM alpine:3.10.2 as base
RUN apk update && apk --no-cache upgrade && apk add --no-cache python3 openssl

FROM base as builder
RUN apk add --no-cache --virtual .build-deps python3-dev gcc ca-certificates libffi-dev openssl-dev build-base
RUN python3 -m venv /opt/venv
# Make sure we use the virtualenv:
ENV PATH="/opt/venv/bin:$PATH"
RUN pip3 install --no-cache-dir ansible

FROM base

COPY --from=builder /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"

docker images

REPOSITORY                              TAG                 IMAGE ID            CREATED             SIZE
ansible                                 0.2                 304de2e8b235        51 seconds ago      165MB

On voit que l’image ne fait plus que 165MB contre 393MB pour la version non optimisée. Ce principe peut être appliqué à plein de cas possible. Par exemple je l’utilise pour générer ce blog en copiant que le code html généré par hugo dans une image nginx-alpine. Résultat l’image ne fait que 9.3 MB


Alimenter un blog comme celui-ci est aussi passionnant que chronophage. En passant votre prochaine commande (n'importe quel autre article) au travers des liens produits ci-contre, je touche une petite commission sans que cela ne vous coûte plus cher. Cela ne me permet pas de gagner ma vie, mais de couvrir les frais inhérents au fonctionnement du site. Merci donc à vous!

comments powered by Disqus