Utilisation des instructions ENTRYPOINT et CMD dans le fichier Dockerfile

Si vous avez déjà eu besoin d’exécuter une ou deux commandes dans votre conteneur Docker au démarrage, ce tutoriel est pour vous. En utilisant les instructions ENTRYPOINT et CMD du Dockerfile, vous pouvez exécuter autant de commandes de démarrage que vous le souhaitez.

Dans ce tutoriel, vous apprendrez à utiliser les instructions ENTRYPOINT et CMD pour exécuter des commandes de démarrage dans un Dockerfile et à comprendre les différences entre elles.

Prérequis

Étant donné que ce tutoriel sera une démonstration pratique, assurez-vous d’avoir les éléments suivants en place :

  • A Windows 10 PC – Windows 10 v10.0.19042 was used in this tutorial.
  • Docker Desktop – Ce tutoriel utilise Docker Desktop v3.3.1.

Création d’un Dockerfile

Avant de pouvoir exécuter des commandes de démarrage de conteneur Docker, vous devez d’abord créer un Dockerfile. Un Dockerfile est un document texte qui contient une liste de commandes pour construire des conteneurs, des images Docker et détermine comment une image Docker est créée.

1. Tout d’abord, ouvrez PowerShell en tant qu’administrateur.

2. Créez un nouveau dossier pour stocker le Dockerfile et tous les fichiers associés que ce tutoriel utilisera et changez de répertoire vers ce dossier. Ce tutoriel utilise ~/docker.

mkdir ~/docker
cd docker

3. Maintenant, créez un fichier texte vierge nommé Dockerfile avec la commande suivante.

cd > Dockerfile

Alternativement, vous pouvez créer un Dockerfile avec la commande suivante si vous êtes sous Linux ou Mac OS.

touch Dockerfile

4. Enfin, ajoutez le contenu suivant dans le Dockerfile

FROM ubuntu:20.04

Vous avez maintenant créé un Dockerfile en devenir!

Construction d’une image Docker

Maintenant que vous avez créé votre Dockerfile, vous devez construire une image Docker pour exécuter les commandes écrites dans vos instructions ENTRYPOINT et CMD du Dockerfile. Une façon de construire une image est d’utiliser la build commande.

En étant dans le répertoire ~/docker, exécutez la commande suivante. La commande ci-dessous crée une image Docker appelée demo (-t demo) à partir du Dockerfile dans ~/docker en spécifiant le répertoire de travail actuel (.).

docker build -t demo .
Building a Docker Image

Exécution d’un conteneur Docker

Après avoir construit l’image Docker, vous aurez besoin d’un conteneur pour exécuter l’image Docker qui exécutera les commandes des instructions ENTRYPOINT et CMD du Dockerfile.

Pour exécuter un conteneur Docker, invoquez la commande run pour créer une couche de conteneur inscriptible sur l’image Docker (demo). L’exemple ci-dessous utilise le paramètre -it pour se connecter de manière interactive au conteneur afin que vous puissiez voir la sortie d’exemple.

docker run -it demo
Running a Docker Container

Forme Exec vs. Shell

Lorsque vous commencez à travailler avec un Dockerfile et à comprendre comment exécuter des commandes de démarrage, vous pouvez rencontrer deux méthodes différentes pour définir ces commandes. Chaque méthode invoquera des commandes mais le fera un peu différemment.

Lorsque Docker exécute des commandes, il peut le faire directement appelé exec ou passer par le shell du conteneur (/bin/sh -c sur Linux ou cmd /S /C sur Windows) appelé shell.

Vous remarquerez que les commandes exécutées via exec ont une instruction suivie des exécutables à invoquer suivis par un ou plusieurs arguments de ligne de commande, comme illustré ci-dessous.

ENTRYPOINT ["executables", "parameter1", "parameter2", ...]
CMD ["executables", "parameter1", "parameter2:, ...]

Écrire des commandes en forme de shell, en revanche, ne nécessite pas d’envelopper les commandes entre crochets, comme illustré ci-dessous.

ENTRYPOINT <command> "parameter1"
CMD <command> "parameter1"

Si vous ne spécifiez pas d’argument à CMD, Docker exécutera toujours la commande sous forme de exec, par exemple CMD <commande>.

Si vous débutez, différencier entre ces deux invocations de commande n’aura pas trop d’importance, mais à mesure que vous deviendrez plus avancé, vous verrez bientôt les avantages et les inconvénients de chacune.

Exécution de Commandes de Démarrage

Passons maintenant à l’essentiel de ce tutoriel et salissons-nous les mains en parcourant quelques exemples d’exécution de commandes de démarrage dans un fichier Docker ENTRYPOINT et des instructions CMD.

1. Ouvrez le Dockerfile que vous avez créé précédemment dans votre éditeur de texte préféré.

2. Copiez et collez le contenu exemple du Dockerfile dans votre Dockerfile, tel que présenté ci-dessous, et enregistrez-le.

Ce Dockerfile crée une couche en utilisant l’image de base ubuntu:20.04. Il indique ensuite à Docker d’appeler la commande echo en lui passant l’argument Hello world à la fois pour les instructions Dockerfile CMD et ENTRYPOINT en utilisant les formes exec et shell.

FROM ubuntu:20.04
# Instruction CMD
CMD ["echo", "Hello world"] # Exec Form
CMD echo "Hello world"      # Shell Form
# Instruction ENTRYPOINT
ENTRYPOINT ["echo", "Hello world"] # Exec Form
ENTRYPOINT echo "Hello world"      # Shell Form

3. Tout en étant dans le répertoire ~/docker, construisez la nouvelle image en exécutant docker build et appelez-la demo. La commande ci-dessous étiquette l’image en tant que demo et recherche un Dockerfile dans le répertoire de travail actuel (.).

docker build -t demo .
Building a Docker image with docker build

4. Maintenant, exécutez un conteneur en utilisant l’image puis exécutez un conteneur Docker basé sur l’image Docker créée précédemment. Vous verrez maintenant que le conteneur renvoie Hello world qui provient de l’instruction CMD fournie dans le Dockerfile.

docker run -it demo
Running a Docker container with docker run

Utilisation de variables dans un fichier Docker

Parfois, vous ne connaissez pas à l’avance les arguments de ligne de commande exacts à transmettre à une commande. Les arguments à passer à une commande ne sont exposés qu’au moment de l’exécution. Plutôt que d’assigner statiquement les arguments de commande, vous pouvez les capturer et les transmettre aux commandes avec des variables.

Vous ne pouvez utiliser que des variables Dockerfile en forme de shell. Docker ne prend pas en charge les variables dans les commandes invoquées via exec.

Ouvrez à nouveau le Dockerfile dans votre éditeur de texte préféré, remplacez tout à l’intérieur par la série de commandes suivante et enregistrez-le.

Vous remarquerez cette fois-ci que le Dockerfile utilise des variables d’environnement et les affiche avec ENV. Dans l’exemple ci-dessous, le Dockerfile définit une variable d’environnement appelée name avec une valeur de friend. Une fois créée, cette variable d’environnement est ensuite référencée via $name.

Lorsque Docker exécute un conteneur basé sur ce Dockerfile, il invoquera la commande echo et transmettra l’argument Welcome, friend.

FROM ubuntu:20.04
ENV name friend

CMD echo "Welcome, $name"
# ou
## ENTRYPOINT echo "Welcome, $name"

Maintenant, créez à nouveau l’image Docker et exécutez le conteneur en fournissant éventuellement un nom de balise shellform. Vous remarquerez que Docker a invoqué la commande echo et a renvoyé la sortie attendue.

Building a Docker Image (shellform) and Running a Docker Container

Combinaison des instructions ENTRYPOINT et CMD du Dockerfile

Beaucoup de temps, vous invoquerez des commandes de démarrage soit dans CMD soit dans l’instruction ENTRYPOINT. Après tout, vous pouvez invoquer autant de commandes que vous le souhaitez en utilisant chaque méthode. Mais vous pouvez aussi invoquer une seule commande et « l’ajouter » en utilisant les deux instructions.

En reprenant les exemples précédents, peut-être avez-vous un Dockerfile qui ressemble à l’exemple ci-dessous. Tel quel, si vous créez une image et exécutez un conteneur à partir de cette image, Docker invoquera la commande echo et renverra Hello.

FROM ubuntu:20.04
ENTRYPOINT ["echo", "Hello"]

Peut-être avez-vous un autre argument que vous souhaitez passer à la commande echo mais pas tout de suite. Peut-être souhaitez-vous le faire plus loin dans le Dockerfile. En appelant l’instruction CMD sans commande, vous pouvez le faire.

Lorsque vous spécifiez une commande à exécuter via l’instruction ENTRYPOINT suivie de l’instruction CMD, Docker suppose automatiquement que la valeur passée à CMD est un argument, pas une commande.

Maintenant, ajoutez une référence à l’instruction CMD sans commande, juste un argument appelé world, comme indiqué ci-dessous.

FROM ubuntu:20.04
ENTRYPOINT ["echo", "Hello"]
CMD ["world"]

Combiner les instructions doit toujours être écrit en forme exécutable en raison de son comportement « similaire à un tableau » de spécification des valeurs individuellement séparées par des virgules au lieu de tout mettre dans une seule chaîne.

Après avoir construit l’image et exécuté le conteneur à partir de l’image, vous pouvez voir qu’au lieu de deux lignes de sortie (Hello et world), Docker ne retourne qu’une seule signifiant une seule invocation de la commande echo.

Building a Docker Image (demo3) and Running a Docker Container

Conclusion

Vous devriez maintenant avoir une bonne compréhension de l’exécution des commandes de démarrage des conteneurs Docker via les instructions du fichier Docker CMD et ENTRYPOINT. Chaque instruction est un peu différente mais accomplit la même tâche et peut même être utilisée ensemble.

Pouvez-vous penser à un scénario où vous préféreriez utiliser CMD plutôt que ENTRYPOINT pour exécuter une commande de démarrage?

Source:
https://adamtheautomator.com/dockerfile-entrypoint/