Différence entre CMD et ENTRYPOINT dans Docker

Isaac Tony 23 aout 2022
  1. la commande CMD dans Docker
  2. la commande ENTRYPOINT dans Docker
  3. Conclusion
Différence entre CMD et ENTRYPOINT dans Docker

Les conteneurs Docker sont devenus la norme en matière de gestion des logiciels et des dépendances dans différents environnements. Vous devrez créer un fichier Docker avant de créer votre image de conteneur d’applications lorsque vous travaillez avec de vraies applications.

Un fichier docker est simplement un document texte en lecture seule avec un ensemble d’instructions qui seront appelées lors de l’assemblage d’une image. Ces commandes incluent RUN, CMD et ENTRYPOINT.

Dans cet article, nous discuterons de l’utilisation de ces commandes. La plupart des développeurs qui en sont probablement aux premiers stades de l’apprentissage de docker ont tendance à utiliser ces commandes de manière interchangeable, ce qui peut vous causer des problèmes.

la commande CMD dans Docker

Cette commande spécifie une instruction exécutée chaque fois que la commande docker RUN est exécutée. Cela nécessite cependant que la commande docker RUN soit exécutée sans spécifier d’arguments.

Lorsque des arguments sont spécifiés, cette commande est remplacée. Par contre, la commande CMD est exécutée si aucun argument de ligne de commande n’est spécifié.

La commande CMD n’est pas obligatoire pour que votre conteneur docker fonctionne correctement puisque la commande ECHO peut être utilisée au moment de l’exécution pour servir le même objectif. Cependant, la commande CMD peut être pratique lors de l’exécution d’un fichier exécutable à chaque démarrage du conteneur.

Pour montrer comment nous pouvons utiliser la commande CMD pour exécuter un fichier exécutable au moment de l’exécution, nous allons créer un simple conteneur docker avec un simple programme flask qui imprime un message. Notez que cela peut être reproduit dans n’importe quel langage, pas nécessairement Python.

Nous allons commencer par créer notre application principale, qui devrait être aussi simple que celle illustrée ci-dessous.

from flask import Flask

app = Flask(__name__)


def hello():
    print("Hello, this is a simple Flask application")


hello()

Au sein du même dossier, nous allons créer notre Dockerfile à l’aide de la commande touch Dockerfile.

Le Dockerfile spécifie uniquement l’image de base, le répertoire de travail et les packages à installer.

Dans la dernière ligne, vous devez noter la commande CMD. Dans ce cas, nous utilisons la commande CMD pour exécuter le fichier app.py au démarrage du conteneur.

#  base image
FROM python

# Set your working directory
WORKDIR /var/www/

# Copy the necessary files
COPY ./app.py /var/www/app.py
COPY ./requirements.txt /var/www/requirements.txt

# Install the necessary packages
RUN pip install -r /var/www/requirements.txt

# Run the app
CMD python3 app.py

Le requirements.txt devrait apparaître comme indiqué ci-dessous.

click==8.0.4
Flask==2.0.3
gunicorn==20.1.0
itsdangerous==2.1.0
Jinja2==3.0.3
MarkupSafe==2.1.0
Werkzeug==2.0.3

Maintenant que tout est prêt, nous pouvons continuer et créer l’image docker. Avant cela, nous devons nous assurer que nous sommes dans le même dossier où notre programme est stocké.

Dans notre cas, nous allons cd dans le dossier my-app avant de construire l’image, comme indiqué ci-dessous.

~/my-app$ docker build -t isaactonyloi_image .

Production:

 => [internal] load build context                                                                                                          0.9s
 => => transferring context: 320B                                                                                                          0.1s
 => [2/5] WORKDIR /var/www/                                                                                                                5.1s
 => [3/5] COPY ./app.py /var/www/app.py                                                                                                    3.2s
 => [4/5] COPY ./requirements.txt /var/www/requirements.txt                                                                                3.2s
 => [5/5] RUN pip install -r /var/www/requirements.txt                                                                                    53.9s
 => exporting to image                                                                                                                     6.9s
 => => exporting layers                                                                                                                    5.8s
 => => writing image sha256:5847e4777754d9d576accd929076bfbee633ca71f049ebe1af6e9bae161f3e96                                               0.1s
 => => naming to docker.io/library/isaactonyloi_image                                                                                      0.2s
isaac@DESKTOP-HV44HT6:~/my-app$

Nous avons construit avec succès notre image basée sur le fichier docker précédent. Nous pouvons le vérifier ci-dessous.

~/my-app$ docker images
REPOSITORY           TAG       IMAGE ID       CREATED         SIZE
isaactonyloi_image   latest    5847e4777754   7 minutes ago   929MB

Nous pouvons enfin créer notre conteneur docker en utilisant la commande docker run basée sur cette image. Notez également que nous ferons cela sans passer d’arguments pour exécuter la commande CMD.

~/my-app$ docker run isaactonyloi_image
Hello, this is a simple Flask application

En plus de cela, la commande CMD nous permet également de créer des arguments qui peuvent être facilement remplacés lors de l’exécution.

Nous avons apporté des modifications à la commande CMD dans l’exemple ci-dessous. Les autres fichiers restent intacts, et nous avons reconstruit une nouvelle image.

# base image
FROM python

# Set your working directory
WORKDIR /var/www/

# Copy the necessary filesls
COPY ./app.py /var/www/app.py
COPY ./requirements.txt /var/www/requirements.txt

# Install the necessary packages
RUN pip install -r /var/www/requirements.txt

# Run the app
CMD ["echo", "Hello, Developer"]

Voici la nouvelle image que nous avons reconstruite à partir de nos modifications apportées au Dockerfile.

~/my-app$ docker images
REPOSITORY           TAG       IMAGE ID       CREATED          SIZE
new_image            latest    73f323be0d2f   25 minutes ago   929MB

Nous devrions recevoir le message sous la commande CMD lors de la création d’un nouveau conteneur Docker sans passer d’argument.

isaac@DESKTOP-HV44HT6:~/my-app$ docker run new_image
Hello, Developer

Cependant, la commande CMD sera automatiquement remplacée lorsque nous passons un argument au moment de l’exécution, et le nouvel argument doit avoir la priorité. Par conséquent, cela nous donne la possibilité d’ajouter de nouveaux arguments au moment de l’exécution, comme indiqué ci-dessous.

~/my-app$ docker run new_image hostname
da0a832888cb

La sortie ci-dessus montre que la commande CMD n’est pas exécutée et remplacée par le nouvel argument de nom d’hôte.

la commande ENTRYPOINT dans Docker

La commande docker ENTRYPOINT présente des similitudes avec la commande CMD, mais pas tout à fait la même.

Lors de l’utilisation de la commande CMD, nous pouvons facilement la remplacer en passant des arguments à l’exécution, mais ce n’est pas le cas avec la commande ENTRYPOINT.

Par conséquent, ENTRYPOINT peut être utilisé pour ne pas remplacer l’instruction de point d’entrée lors de l’exécution.

Comme indiqué ci-dessous, nous pouvons explorer le fonctionnement de cette commande en remplaçant simplement la commande CMD par la commande ENTRYPOINT dans notre Dockerfile. Nous allons construire une nouvelle image basée sur nos modifications apportées au fichier docker.

isaac@DESKTOP-HV44HT6:~/my-app$ docker build -t tonyloi_newimage .
[+] Building 42.7s (10/10) FINISHED

Production:

 => [internal] load build definition from Dockerfile                                                                                                                          2.0s
 => => transferring dockerfile: 365B                                                                                                                                          0.7s
 => [internal] load .dockerignore                                                                                                                                             1.6s
 => => transferring context: 2B                                                                                                                                               0.4s
 => [internal] load metadata for docker.io/library/python:latest                                                                                                             35.4s
 => [1/5] FROM docker.io/library/python@sha256:c90e15c86e2ebe71244a2a51bc7f094554422c159ce309a6faadb6debd5a6df0                                                               0.3s
 => [internal] load build context                                                                                                                                             1.2s
 => => transferring context: 63B                                                                                                                                              0.1s
 => CACHED [2/5] WORKDIR /var/www/                                                                                                                                            0.0s
 => CACHED [3/5] COPY ./app.py /var/www/app.py                                                                                                                                0.0s
 => CACHED [4/5] COPY ./requirements.txt /var/www/requirements.txt                                                                                                            0.0s
 => CACHED [5/5] RUN pip install -r /var/www/requirements.txt                                                                                                                 0.0s
 => exporting to image                                                                                                                                                        2.1s
 => => exporting layers                                                                                                                                                       0.0s
 => => writing image sha256:15fb8e4e3ff58ed529b11342bba75b029fd4323beb24aac70ca36b178d04cb34                                                                                  0.2s
 => => naming to docker.io/library/tonyloi_newimage                                                                                                                           0.1s
isaac@DESKTOP-HV44HT6:~/my-app$

Cette sortie est un témoignage que nous avons réussi à construire une nouvelle image. Nous pouvons maintenant créer un nouveau conteneur Docker basé sur cette image.

Vous pouvez choisir de créer le conteneur en utilisant le nom de l’image ou l’identifiant de l’image, tous deux accessibles à l’aide de la commande docker images. Cela affichera également les images que nous avons créées auparavant.

~/my-app$ docker images
REPOSITORY           TAG       IMAGE ID       CREATED          SIZE
tonyloi_newimage     latest    15fb8e4e3ff5   48 minutes ago   929MB
new_image            latest    73f323be0d2f   48 minutes ago   929MB
isaactonyloi_image   latest    5847e4777754   48 minutes ago   929MB

Si nous construisons notre conteneur Docker sans ajouter d’arguments, nous devrions obtenir une sortie comme ci-dessous.

isaac@DESKTOP-HV44HT6:~/my-app$ docker run tonyloi_newimage
Hello, Developer

Si nous essayons de passer des arguments lors de la création d’un autre conteneur basé sur cette image, vous remarquerez que, contrairement au cas de la commande CMD, ces nouveaux arguments ne remplacent pas la commande ENTRYPOINT.

Nous pouvons le vérifier ci-dessous.

isaac@DESKTOP-HV44HT6:~/my-app$ docker run tonyloi_newimage Welcome to ADC
Hello, Developer Welcome to ADC

Conclusion

Nous pouvons affirmer que ces deux commandes sont très similaires ; cependant, leur différence est que la commande CMD peut être remplacée lors de l’exécution alors que la commande ENTRYPOINT ne le peut pas.

De plus, certaines situations peuvent justifier l’utilisation simultanée des deux commandes.

Auteur: Isaac Tony
Isaac Tony avatar Isaac Tony avatar

Isaac Tony is a professional software developer and technical writer fascinated by Tech and productivity. He helps large technical organizations communicate their message clearly through writing.

LinkedIn

Article connexe - Docker Command