Construire une image de conteneur
Objectifs :
-
Construire une image à partir d'un
Dockerfile
-
Publier cette image sur Docker Hub
Contenu d'un Dockerfile
Nous avons déjà eu l'occasion de voir un Dockerfile
. Voici un petit aperçu
des instructions que nous pouvons y trouver :
-
FROM
- indique l'image de départ sur laquelle on va se baser. -
CMD
- Définit la commande à exécuter lors du lancement de l'image. Peut également être utilisé pour définir l'argument par défaut de l'instructionENTRYPOINT
. -
RUN
- Exécute une commande pour contribuer à la construction de votre image. -
EXPOSE
- Ouvre un ou plusieurs ports du réseau. -
VOLUME
- Crée un point de montage. -
COPY
- Ajoute un fichier dans l'image. -
LABEL
- Ajoute des métadonnées à l'image dans un format clé/valeur. -
ENV
- Définit une variable d'environnement. -
ENTRYPOINT
- Détermine l'exécutable qui doit être lancé au démarrage du conteneur. UtilisezCMD
pour passer des options à cet exécutable.
Prenons un Dockerfile
pour voir le rapport entre les instructions
ENTRYPOINT
et CMD
:
$ cat Dockerfile
FROM rockylinux:latest
LABEL maintainer="Microlinux <info@microlinux.fr>"
ENTRYPOINT ["/usr/bin/ping"]
CMD ["www.docker.com"]
-
Nous utilisons la dernière image Rocky Linux comme base pour notre image personnalisée.
-
La deuxième ligne est une instruction
LABEL
, avec une paire clé/valeur. Ici, la clé estmaintainer
, suivie d'un signe égal, puis de la valeurMicrolinux <info@microlinux.fr>
entre guillemets. Nous ajoutons simplement des métadonnées à notre image. -
L'instruction
ENTRYPOINT
fait en sorte que le conteneur exécute la commande/usr/bin/ping
au démarrage. -
Notez que
/usr/bin/ping
est entouré de guillemets et de crochets. Le format utilisé ici est un tableau JSON. -
L'instruction
CMD
utilise également un tableau JSON. Ici, nous fournissonswww.docker.com
comme argument àENTRYPOINT
. -
Au final, la commande qui va être exécutée sera
/usr/bin/ping www.docker.com
. -
Lorsque vous créez un
Dockerfile
, il vaut mieux le nommerDockerfile
.
La commande docker build
permet de construire l'image :
$ docker build -t kikinovak/dockerping:latest .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM rockylinux:latest
---> c830f8e8f82b
Step 2/4 : LABEL maintainer="Microlinux <info@microlinux.fr>"
---> Running in ea304425eb7e
Removing intermediate container ea304425eb7e
---> 76ce20858571
Step 3/4 : ENTRYPOINT ["/usr/bin/ping"]
---> Running in 714f2f366b76
Removing intermediate container 714f2f366b76
---> f53922b2b819
Step 4/4 : CMD ["www.docker.com"]
---> Running in be1a6fbcbdb3
Removing intermediate container be1a6fbcbdb3
---> f2483023f694
Successfully built f2483023f694
Successfully tagged kikinovak/dockerping:latest
-
L'option
-t
permet de spécifier un nom et un tag pour l'image. -
Notez le format utilisé pour le nom de l'image : identifiant Docker + barre oblique + nom du dépôt + deux-points + tag.
-
Si vous ne fournissez pas de tag, la valeur
latest
est présumée. Nous explicitions cette information ici par souci de précision. -
La commande
docker build
attend un chemin où elle pourra trouver unDockerfile
utilisé pour construire l'image. Le point.
indique àdocker build
qu'il faut utiliser leDockerfile
dans le répertoire courant.
Vérifions si l'image est bien disponible :
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
kikinovak/dockerping latest f2483023f694 45 seconds ago 205MB
rockylinux latest c830f8e8f82b 9 days ago 205MB
Notez que nous avons deux images :
-
Dans un premier temps, Docker a téléchargé notre image de base, qui est
rockylinux:latest
, et qui correspond à l'instructionFROM
de notreDockerfile
. -
Ensuite, Docker a exécuté les commandes et les instructions de notre
Dockerfile
pour créer l'imagekikinovak/dockerping
.
Maintenant que j'ai mon image, je peux la publier sur Docker Hub. Pour ce faire, je dois d'abord m'authentifier avec mon identifiant Docker :
$ docker login
Authenticating with existing credentials...
...
Login Succeeded
À présent, je peux télécharger mon image sur Docker Hub :
$ docker push kikinovak/dockerping
Using default tag: latest
The push refers to repository [docker.io/kikinovak/dockerping]
b9674b668e06: Mounted from library/rockylinux
latest: digest: sha256:8fd30a6170de239ec761b42cc3a7b91412c0... size: 529
Je vérifie si mon image apparaît bien sur Docker Hub :
Je retourne dans ma console et je lance mon image :
$ docker run kikinovak/dockerping
PING d1syzps6kort6n.cloudfront.net (52.222.174.72) 56(84) bytes of data.
64 bytes from server-52-222-174-72.fra54.r.cloudfront.net (52.222.174.72):
icmp_seq=1 ttl=241 time=28.6 ms
64 bytes from server-52-222-174-72.fra54.r.cloudfront.net (52.222.174.72):
icmp_seq=2 ttl=241 time=28.4 ms
64 bytes from server-52-222-174-72.fra54.r.cloudfront.net (52.222.174.72):
icmp_seq=3 ttl=241 time=28.3 ms
Notre conteneur tourne et envoie une série de ping
vers docker.com
.
Appuyez sur Ctrl+C pour l'arrêter.
Rappelons-nous le contenu du Dockerfile
utilisé pour créer cette image :
ENTRYPOINT ["/bin/ping"]
CMD ["www.docker.com"]
La valeur par défaut de CMD
peut être substituée en fournissant une option en
ligne de commande :
$ docker run kikinovak/dockerping google.fr
PING google.fr (142.250.74.227) 56(84) bytes of data.
64 bytes from par10s40-in-f3.1e100.net (142.250.74.227): icmp_seq=1 ttl=118
time=19.9 ms
64 bytes from par10s40-in-f3.1e100.net (142.250.74.227): icmp_seq=2 ttl=118
time=19.8 ms
64 bytes from par10s40-in-f3.1e100.net (142.250.74.227): icmp_seq=3 ttl=118
time=19.10 ms
Dans l'exemple ci-dessus, la commande ping
utilisée était déjà présente dans
l'image de base. Or, dans certains cas, le ou les logiciels utilisés peuvent ne
pas être présents dans l'image de départ. Si nous nous étions basés sur l'image
de Debian, voici ce que nous aurions obtenu :
$ docker pull debian:latest
$ docker run -it --name debianping debian:latest
root@c098cce01e95:/# ping docker.com
bash: ping: command not found
Dans ce cas, nous pouvons très bien ajouter la ou les commandes en question. En l'occurrence :
root@c098cce01e95:/# apt update
...
root@c098cce01e95:/# apt install iputils-ping
...
root@c098cce01e95:/# which ping
/bin/ping
root@c098cce01e95:/# ping docker.com
PING docker.com (141.193.213.20) 56(84) bytes of data.
64 bytes from 141.193.213.20 (141.193.213.20): icmp_seq=1 ttl=57 time=21.6 ms
64 bytes from 141.193.213.20 (141.193.213.20): icmp_seq=2 ttl=57 time=21.2 ms
64 bytes from 141.193.213.20 (141.193.213.20): icmp_seq=3 ttl=57 time=21.7 ms
Voici le Dockerfile
qui va nous permettre de réaliser cette opération :
$ cat Dockerfile
FROM debian:latest
LABEL maintainer="Microlinux <info@microlinux.fr>"
RUN apt-get update \
&& apt-get install -y iputils-ping \
&& apt-get clean
ENTRYPOINT ["/bin/ping"]
CMD ["www.docker.com"]
-
Debian utilise les gestionnaires de paquets
apt
etapt-get
. Le premier est plutôt utilisé de manière interactive, alors que le second servira plutôt dans les scripts. -
Nous regroupons toutes les commandes
apt-get
en une seule instructionRUN
de manière à produire une seule couche par-dessus l'image de base. -
Théoriquement nous pourrions très bien nous servir de plusieurs commandes
RUN
, mais chacune d'entre elles résulterait en une couche supplémentaire. -
L'antislash
\
en fin de ligne est simplement utilisé pour améliorer la lisibilité duDockerfile
. -
La commande
apt-get clean
sert à supprimer les paquets téléchargés, ce qui nous permet de réduire la taille de l'image résultante.
Construisez et exécutez cette image :
$ docker build -t kikinovak/debianping .
...
$ docker run kikinovak/debianping
PING emzm5pam37e4.wpeproxy.com (141.193.213.20) 56(84) bytes of data.
64 bytes from 141.193.213.20 (141.193.213.20): icmp_seq=1 ttl=57 time=21.1 ms
64 bytes from 141.193.213.20 (141.193.213.20): icmp_seq=2 ttl=57 time=21.2 ms
64 bytes from 141.193.213.20 (141.193.213.20): icmp_seq=3 ttl=57 time=21.2 ms
Notre image fonctionne comme prévu, nous pouvons donc la publier sur Docker Hub :
$ docker push kikinovak/debianping
Using default tag: latest
The push refers to repository [docker.io/kikinovak/debianping]
cdb2a396502f: Pushed
c9a63110150b: Mounted from kikinovak/dockerping
latest: digest: sha256:8ea7476028d70b638e6bb17da7f33cf512b0fa556... size: 741
Exercice 1
-
Construisez un conteneur
nettools:latest
basé sur la dernière image de Debian, et qui comprend les commandesping
,traceroute
etcurl
. Le shell Bash devra être lancé au démarrage du conteneur. -
Lancez le conteneur
nettools
et invoquez successivement les commandesping -c 3 google.fr
,curl google.fr
ettraceroute google.fr
. -
Quittez le conteneur et faites un brin de ménage.
Exercice 2
-
Lancez un conteneur nommé
rockyvim
basé sur Rocky Linux 8.5 et connectez-vous au shell Bash de ce conteneur. -
Installez l'éditeur de texte Vim de manière interactive.
-
Lancez Vim pour vérifier si tout va bien.
-
Quittez le conteneur.
-
Construisez une image personnalisée
rockyvim:latest
basée sur Rocky Linux 8.5 et qui contient l'éditeur Vim.
Exercice 3
-
Connectez-vous à Docker Hub.
-
Publiez les deux images personnalisées
nettools:latest
etrockyvim:latest
sur Docker Hub.
La rédaction de ces cours demande du temps et des quantités significatives de café espresso. Vous appréciez cette formation ? Offrez un café au formateur en cliquant sur la tasse.