3.3. Gestion des images

Les images étant les “plans de fabrication” des containers, elles sont un élément essentiel à maitriser pour exploiter ces derniers à bon escient.  Il est important de pouvoir les sélectionner, les manipuler, et également les créer.  

Récupération et partage d’image

Pour lister les images disponibles sur un hôte, les deux commandes ci-dessous peuvent être utilisées :  

docker images

docker image ls

Pour récupérer une image depuis un repository distant (Docker Hub par défaut), on utilise : 

docker (image) pull <nom de l'image>

On a constaté dans notre exemple de la section 3.1 que lorsqu’un docker run est effectué sur une image absente, Docker s’occupait de la télécharger depuis le Docker Hub.  En pratique, il a effectué l’équivalent d’un “docker pull nginx”.  

A l’inverse, il est également possible d’uploader une image personnelle depuis un hôte vers un repository distant pour la partager ou bien l’utiliser sur d’autres machines.   

Ainsi, pour envoyer une image sur le DockerHub, on utilise la commande suivante, après s’être identifié :  

docker (image) push <nom de l'image>

Création d’image

Deux techniques sont possibles pour créer des images : 

  • Partir d’un container en cours d’exécution, et en effectuer un “snapshot” : Enregistrer son état actuel (couche supérieure inscriptible) par dessus  les couches de l’image d’origine du conteneur pour en faire une nouvelle image.  C’est l’opération docker commit.  Cette technique permet de configurer un container à la main, puis, une fois l’état visé obtenu, de sauvegarder cette configuration dans une image. L’inconvénient de cette méthode est que l’historique des opérations appliquées pour obtenir l’image n’est plus accessible.
  • Créer une image depuis une image de base (généralement une distribution Linux), en listant les opérations nécessaires pour adapter cette image de base à l’usage applicatif prévu.  Ces opérations consistent soit à exécuter des commandes, soit à copier des fichiers dans le système de fichiers cible, ou encore à configurer les paramètres d’exécution des futurs containers (ports, variables d’environnemnet, commande de démarrage, …).  Chaque étape de construction de l’image représente une nouvelle couche par dessus l’image de base.  Il s’agit en fait de rédiger le “plan de construction” de l’image.  Cela se fait dans un fichier spécifique appelé Dockerfile. Contrairement à la première méthode, l’utilisation d’un Dockerfile permet de documenter explicitement les opérations effectuées pour obtenir l’image.
    Construction d'un container depuis une image
Création d'une image depuis un Dockerfile

Fichiers Dockerfile

Un fichier Dockerfile est un simple fichier texte listant des commandes.  Les principales sont : 

  • FROM <image> : Indique l’image de base par dessus laquelle la nouvelle image sera construite.  
  • MAINTAINER <nom> : Documente le nom du responsable du fichier
  • RUN <commande>: Indique une commande à exécuter dans la nouvelle couche à rajouter sur le système de fichiers. 
  • COPY <src> <dst> : Copie un fichier depuis l’hôte (au départ du répertoire source) vers la destination, à savoir le système de fichiers de l’image
  • ENV <key> <value> : Définit une variable d’environnement pour l’image
  • EXPOSE <port> : Indique que l’application qui tournera dans le container écoutera sur le port indiqué.  Cette instruction ne modifie pas le comportement du container ni ne rend le port accessible de l’extérieur.  Il s’agit juste d’une documentation de l’existence de cette ouverture de port pour le futur utilisateur de l’image.  
  • VOLUME <point de montage> : Indique un répertoire de montage pour un volume.  Le nom du volume sera spécifié lors du lancement du container.  
  • CMD [<commande>] : Indique quelle commande exécuter au démarrage du container, si aucune commande n’a été indiquée dans le “docker run
  • ENTRYPOINT [<commande>] : Indique également la commande de démarrage du container.  Contrairement à CMD, lorsque ENTRYPOINT est utilisé, le dernier paramètre du ‘docker run’ ne va pas écraser la commande ENTRYPOINT mais y être concaténé. 

Pour construire une image sur base d’un Dockerfile, on utilise la commande docker build : 

docker build -t <tag> <chemin du Dockerfile>

Le tag sera utilisé comme identifiant de l’image.  

Dans l’exemple du screencast ci-dessous, une image représentant un simple poste client avec quelques outils de débugging est construite.  Le Dockerfile est très simple, et comporte trois lignes : 

  • L’image de base (ubuntu)
  • Un RUN qui sert à installer les outils nécessaires (après un apt-update)
  • le CMD, qui se contente de lancer un shell. 

Ces trois lignes définissent trois couches sur l’image de base.

Screencast illustrant un docker build

On assiste lors du premier build à l’installation des packages demandés. Notez cependant qu’au second build, comme les couches intermédiaires sont restées en cache, l’image n’est pas réellement reconstruite.  On peut clairement observer les trois étapes de la construction de l’image qui génèrent chacune une couche supplémentaire, identifiée par un hash.  

Référence Dockerfile : https://docs.docker.com/engine/reference/builder/