Sommaire
- Cycle de vie des images et des conteneurs
- Dockerfile
- Créer un fichier Dockerfile
- Créer une image
- Démarrer un conteneur
- Accéder au Shell du conteneur démarré
- Surcharger la commande lancée au démarrage du conteneur
- Supprimer un conteneur et son image
- Commandes groupées
- Modifier et recréer une image et démarrer son conteneur
- Démarrer le conteneur en tâche de fond
Pré-requis
Cet article nécessite de disposer d'une machine Linux.Sous Windows, vous pouvez suivre l'installation rapide suivante : Installation rapide de Docker avec Vagrant et VirtualBox sur Windows
Il faut également avoir lu l'article sur la présentation de Docker : Présentation de Docker
Cycle de vie des images et des conteneurs
Avec Docker, on part d'un fichier Dockerfile pour construire une image de conteneur. Cette image servira à démarrer des conteneurs qui utiliseront le contenu de cette image.
Voici un schéma illustrant le cycle de vie d'un conteneur avec les commandes du client Docker :
Dockerfile
Le fichier Dockerfile décrit comment une image est construite. La commande
docker build
construit une image à partir de ce fichier Dockerfile.Syntaxe
Voici la syntaxe du Dockerfile pour décrire l'image et la manière dont elle est créée :
MAINTAINER <name>
- Auteur de l'image
FROM <image>
- nom de l'image de base existante qui sert de base à l'image à créer afin de ne pas partir de rient de tout mais du contenu d'une image existante
- pour une image fonctionnant sur Ubuntu, l'image de base peut être Ubuntu
ENV <key> <value>
- Définir une variable d'environnement
ADD <src> <dest>
- Ajoute un fichier local dans l'image
VOLUME ["/<dir>"]
- Répertoire monté au démarrage du conteneur qui est externe au conteneur.
- Ceci permet de conserver les fichiers après arrêt du conteneur
- Voir documentation : Sharing Directories using volumes
USER <user>
- Indique l'utilisateur Linux utilisé lors du démarrage du conteneur
EXPOSE <port>
- Indique le port réseau exposé par le conteneur
- Ceci est utilisé pour définir sur quels ports réseau communiquent les conteneurs entre eux ou vers l'extérieur de la machine hôte de Docker
- Voir documentation :
- Linking containers together : configuration de l'interconnexion réseau entre conteneurs
- Network Configuration : configuration des redirections de port sur la machine hôte
RUN <command>
RUN ["executable", "param1", "param2"]
- Exécute la commande sur l'image
CMD <command>
CMD ["executable", "param1", "param2"]
- Il ne doit y avoir qu'un seul CMD dans le fichier Dockerfile
- Il s'agit de la commande qui est lancée à chaque démarrage d'un conteneur basé sur cette image : par exemple, si l'image contient le serveur Tomcat, il peut s'agir de lancer l'exécution du serveur Tomcat au démarrage du conteneur
- La commande n'est lancée qu'à l'exécution du conteneur et non durant la construction de l'image
- Cette commande peut être redéfinie dans la commande de lancement du conteneur
Exemple
Voici un exemple simple de fichier Dockerfile :
- La ligne
FROM
indique que cette image se base sur l'image officielleubuntu
en version 14.04 disponible sur le registry public de Docker. - La commande suivante
RUN apt-get update
lance la mise à jour des packages Linux. - Enfin la dernière ligne
CMD
définit la commande qui sera lancée au démarrage du conteneur (et non lors de la création de l'image) qui est ici de lancer un shell Bash.
Créer le fichier Dockerfile
Nous pouvons tester la construction de cette image en créant le fichierDockerfile
et en lançant la construction de l'image :- Ouvrir un terminal de commandes
- Se connecter à la VM de Vagrant via la commande :
vagrant ssh
- Ne pas définir de passphrase
- Le mot de passe est :
vagrant
- Passer en utilisateur
root
:sudo su
- Créer le répertoire
image1
:mkdir image1
- Créer le fichier
Dockerfile
:curl -o image1/Dockerfile https://gist.githubusercontent.com/ludo1026/9356580e889c777ec771/raw/df4f61a01f541fcf81f53b91e11516704a212dc8/Dockerfile
- Vérifier le contenu du fichier
Dockerfile
via la commande suivante : cat image1/Dockerfile
- Le fichier
Dockerfile
doit avoir le contenu suivant :
Créer l'image à partir du fichier Dockerfile
- Lancer la commande de création de l'image en indiquant le nom du répertoire contenant le fichier
Dockerfile
, iciimage1
:docker build -t image1 image1
- L'option
-t image1
n'est pas obligatoire : elle permet de nommer et de tagguer l'image dans le registry afin de la retrouver facilement - Docker télécharge l'image de base Ubuntu 14.04
- Il lance ensuite la commande
RUN
pour mettre à jour les packages Linux dans l'image - Docker stocke l'image en local
- Dans la sortie console de la commande
docker build
, la ligne suivante indique l'identifiant de l'image qui vient d'être créée :Successfully built <identifiant>
- L'identifiant de l'image, exemple: 231fc2fcbf5a, est à utiliser dans les commandes docker pour référencer l'image
- Lancer la commande pour visualiser les images disponibles en local :
docker images
- Le nom du tag
image1
permet de repérer l'image qui vient d'être créée - L'image de base
ubuntu
déclarée dans leFROM
du fichierDockerfile
a aussi été téléchargée et visible dans la liste des images du registry local de Docker - La colonne
IMAGE ID
contient l'identifiant de l'image.
Démarrer un conteneur à partir de l'image
Maintenant que nous venons de créer l'image, nous pouvons lancer l'exécution d'un nouveau conteneur à partir de cette image :
- Lancer la commande suivante pour démarrer un conteneur à partir de l'image que nous venons de créer en indiquant l'identifiant de l'image qui a été récupéré via la commande
docker images
(colonneIMAGE ID ) :docker run <identifiant>
- La sortie console de cette commande affiche "Hello !" :
- il s'agit de la commande
echo "Hello !"
définie par la ligneCMD
à la fin du fichierDockerfile
et qui a été exécuté par Docker au démarrage du conteneur - Cette commande ne lance pas de processus qui tourne en permanence ou en tâche de fond, c'est pourquoi Docker arrête l'exécution du conteneur.
- Lancer la commande suivante pour voir la liste des processus en cours d'exécution :
docker ps
- Le conteneur qui vient d'être exécuté n'est pas visible
- Lancer la commande suivante pour voir la liste de tous les processus, même ceux arrêtés :
docker ps -a
- Le conteneur qui vient d'être exécuté est indiqué comme arrêté :
STATUS : Exit 0
- La colonne
CONTAINER ID
contient l'identifiant du conteneur - La colonne
IMAGE
contient l'identifiant de l'image
Accéder au shell du conteneur démarré
Au démarrage du conteneur, il est possible d'ouvrir une session Shell sur ce conteneur.
Il faut ajouter les options
-i
et -t
à la commande docker run
.docker run -i -t <identifiant>
- Lancer la commande suivante :
docker run -i -t image1
- Nous accédons au shell du conteneur
- Le conteneur reste en cours d'exécution même s'il n'y a pas de processus qui tourne dans ce conteneur
- Nous pouvons lancer des processus ou apporter des modifications au conteneur via ce shell
Surcharger la commande lancée au démarrage du conteneur
La commande
docker run
permet de surcharger la commande lancée au démarrage du conteneur en indiquant la commande shell à lancer à la fin de la commande docker run
.docker run <identifiant> <commande shell>
- Démarrer un conteneur en utilisant la commande
echo Bonjour
qui sera utilisée au démarrage du conteneur à la place de la commandeecho "Hello !"
contenue dans l'image :
docker run <identifiant> echo Bonjour
- La console affiche "Bonjour" au lieu d'afficher "Hello !"
Supprimer l'image et le conteneur
Nous devons supprimer le conteneur avant l'image, sinon docker affiche un message d'erreur. Ce message contient les identifiants des conteneurs qui utilisent cette image.Supprimer le conteneur
Note : Un conteneur ne peut être supprimé s'il est en cours d'exécution.-
Pour supprimer le conteneur, il faut lancer la commande suivante pour récupérer l'identifiant du conteneur :
docker ps -a
- La colonne
CONTAINER ID
contient l'identifiant du conteneur - La colonne
IMAGE
contient le nom de l'image -
Lancer la commande de suppression du conteneur :
docker rm <identifiant>
-
Vérifier que le conteneur n'existe plus via la commande :
docker ps -a
Supprimer l'image
-
Pour supprimer l'image, il faut lancer la commande suivante pour récupérer l'identifiant de l'image :
docker images
- La colonne
IMAGE ID
contient l'identifiant de l'image -
Lancer la commande de suppression de l'image :
docker rmi <identifiant>
-
Vérifier que l'image n'existe plus via la commande :
docker images
Commandes groupées
Il est également possible d'arrêter et de supprimer plusieurs conteneurs et plusieurs images en une seule commande :
Arrêter
- Arrêter tous les conteneurs :
docker ps|sed "1 d"|awk '{print $1}'|xargs docker stop
- Arrêter les conteneurs d'une même image (ici "image1"):
docker ps|sed "1 d"|grep "image1"|awk '{print $1}'|xargs docker stop
Supprimer
- Supprimer tous les conteneurs :
docker ps -a|sed "1 d"|awk '{print $1}'|xargs docker rm
- Supprimer les conteneurs d'une même image (ici "image1"):
docker ps -a|sed "1 d"|grep "image1"|awk '{print $1}'|xargs docker rm
- Supprimer les conteneurs arrêtés :
docker ps -a|sed "1 d"|grep "Exit"|awk '{print $1}'|xargs docker rm
- Supprimer toutes les images :
docker images|sed "1 d"|awk '{print $3}'|sort|uniq|xargs docker rmi
- Supprimer les images selon leur nom (ici "image1") :
docker images|sed "1 d"|grep "image1"|awk '{print $3}'|sort|uniq|xargs docker rmi
- Supprimer les images qui n'ont pas été tagguées (valeur "<none>") :
docker images|sed "1 d"|grep \<none\>|awk '{print $3}'|sort|uniq|xargs docker rmi
Recréer l'image et démarrer un conteneur
Maintenant que les conteneurs et l'imageimage1
n'existent plus, nous pouvons créer une image qui lancera un processus qui ne s'arrête pas.Pour cela, nous modifions le fichier
Dockerfile
afin d'y définir le processus qui ne s'arrête pas :
- Ouvrir le fichier
Dockerfile
:nano image1/Dockerfile
- Remplacer la dernière ligne par celle-ci :
CMD while true; do ps -aux; sleep 2; done
- Supprimer la ligne qui effectue la mise à jour des packages Linux :
RUN apt-get update
- Lancer la création de l'image :
docker build -t image1 image1
- Récupérer l'identifiant de cette image via la commande :
docker images
- Lancer l'exécution du conteneur à partir de cette image :
docker run <identifiant de l'image>
La commande
La liste des processus du conteneur est affichée sur la console de la machine hôte.
Cependant, la commande
Pour lancer le conteneur en tâche de fond, lancer la commande
Il est nécessaire d'arrêter le conteneur avant de le supprimer.
ps -aux
est lancée toutes les 2 secondes sur le conteneur.La liste des processus du conteneur est affichée sur la console de la machine hôte.
Cependant, la commande
docker run
ne lance pas l'exécution du conteneur en tâche de fond :- La liste des processus du conteneur s'affiche toutes les 2 secondes sur la sortie console de la machine hôte
- Faire
CTRL + C
pour arrêter l'exécution du conteneur - La commande
docker ps -a
indique que le conteneur est arrêté
Exécuter le conteneur en tâche de fond (mode détaché)
Pour lancer le conteneur en tâche de fond, lancer la commande
docker run
avec l'option -d
:- Lancer l'exécution de notre conteneur en mode détaché :
docker run -d <identifiant>
- le conteneur tourne en tâche de fond via le démon de Docker
- aucune sortie console n'est affichée
- Afficher les conteneurs en cours d'exécution :
docker ps
- Notre conteneur est dans la liste des conteneurs en cours d'exécution
- La colonne
STATUS
indique que le conteneur est en cours d'exécution depuis 20 secondes :Up 20 seconds
- Le processus lancé dans le conteneur est visible via la commande
ps -aux
depuis la machine hôte : - Nous pouvons afficher la sortie console du conteneur sur la sortie console de la machine hôte :
docker logs <identifiant>
Arrêter le conteneur
- Lister les conteneurs en cours d'exécution :
docker ps
- Arrêter le conteneur :
docker stop <identifiant>
- Il est possible de relancer l'exécution du conteneur qui vient d'être arrêté via la commande :
docker start <identifiant>
Conclusion
L'objectif de cet article était de s'entraîner avec la création d'images et l'exécution des conteneurs.
Nous verrons dans un prochain article comment utiliser des images fournies par la communauté pour monter rapidement des serveurs Tomcat et des base de données.