Différence entre RUN et CMD dans un Dockerfile

293

Je suis confus quand dois - je utiliser CMDvs RUN. Par exemple, pour exécuter des commandes bash / shell (c'est-à-dire ls -la), j'utiliserais toujours CMDou y a-t-il une situation où j'utiliserais RUN? Essayer de comprendre les meilleures pratiques concernant ces deux Dockerfiledirectives similaires .

TakeSoUp
la source

Réponses:

425

RUN est une étape de création d'image, l'état du conteneur après qu'une RUNcommande sera validée dans l'image du conteneur. Un Dockerfile peut comporter de nombreuses RUNétapes qui se superposent pour créer l'image.

CMD est la commande que le conteneur exécute par défaut lorsque vous lancez l'image construite. Un Dockerfile n'utilisera que la finale CMDdéfinie. Le CMDpeut être remplacé lors du démarrage d'un conteneur avec docker run $image $other_command.

ENTRYPOINT est également étroitement lié à CMDet peut modifier la façon dont un conteneur démarre une image.

Mat
la source
15
vous faites tout le RUNnécessaire pour configurer votre environnement, et votre (uniquement) CMD lance le processus en cours d'exécution dans votre conteneur, par exemple, pour nginx, extrait de github.com/nginxinc/docker-nginx/blob/… vous voyez la ligneCMD ["nginx", "-g", "daemon off;"]
user2915097
"Un Dockerfile ne peut avoir qu'un seul CMD" - pas techniquement vrai, mais en fait, tous sauf un seront ignorés. Voir la réponse de GingerBeer.
Colm Bhandal
"Un Dockerfile n'utilisera que le CMD final défini"? en fait, le CMD final défini sera utilisé pour lancer l'image en tant que conteneur, non?
paul cheung
1
Oui @paulcheung la dernière commande du dockerfile est écrite dans l'image et est la commande que le conteneur exécute par défaut lorsque vous lancez l'image construite.
Matt
126

RUN - la commande se déclenche pendant que nous construisons l'image docker.

CMD - la commande se déclenche pendant que nous lançons l'image de docker créée.

Nisal Edu
la source
67

J'ai trouvé cet article très utile pour comprendre la différence entre eux:

RUN - L'instruction RUN vous permet d'installer votre application et les packages nécessaires. Il exécute toutes les commandes au-dessus de l'image actuelle et crée un nouveau calque en validant les résultats. Souvent, vous trouverez plusieurs instructions RUN dans un Dockerfile.

CMD - L'instruction CMD vous permet de définir une commande par défaut, qui ne sera exécutée que lorsque vous exécuterez le conteneur sans spécifier de commande. Si le conteneur Docker s'exécute avec une commande, la commande par défaut sera ignorée. Si Dockerfile a plus d'une instruction CMD, toutes les
instructions CMD sauf la dernière sont ignorées.

fay
la source
13

RUN - Installez Python, votre conteneur a maintenant python gravé dans son image
CMD - python hello.py, exécutez votre script préféré

Rohit Salecha
la source
CMD - Installer Python, mon conteneur maintenant n'a-t-il pas python gravé dans son image?
Carlos Fontes
RUN créera une couche d'image de python, CMD exécutera simplement la commande de ne pas créer l'image
Rohit Salecha
8

Commande RUN: La commande RUN exécutera essentiellement la commande par défaut lorsque nous construisons l'image. Il va également valider les modifications d'image pour l'étape suivante.

Il peut y avoir plus d'une commande RUN pour faciliter le processus de création d'une nouvelle image.

Commande CMD: les commandes CMD définissent simplement la commande par défaut pour le nouveau conteneur. Cela ne sera pas exécuté au moment de la construction.

Si un fichier Docker contient plus de 1 commandes CMD, toutes sont ignorées, sauf la dernière. Comme cette commande n'exécutera rien mais définira simplement la commande par défaut.

Bière de gingembre
la source
6

Remarque: Ne confondez pas RUN avec CMD. RUN exécute en fait une commande et valide le résultat; CMD n'exécute rien au moment de la génération, mais spécifie la commande prévue pour l'image.

à partir de la référence du fichier docker

https://docs.docker.com/engine/reference/builder/#cmd

Elsayed
la source
4

RUN : peut être multiple et il est utilisé dans le processus de construction , par exemple installer plusieurs bibliothèques

CMD : ne peut avoir que 1, qui est votre point de départ d' exécution (par exemple ["npm", "start"], ["node", "app.js"])

Xin
la source
2

Les réponses existantes couvrent l'essentiel de ce dont aurait besoin toute personne examinant cette question. Je vais donc couvrir quelques domaines de niche pour CMD et RUN.

CMD: les doublons sont autorisés mais inutiles

GingerBeer fait un point important: vous n'obtiendrez aucune erreur si vous mettez plus d'un CMD - mais c'est inutile de le faire. Je voudrais développer un exemple:

FROM busybox
CMD echo "Executing CMD"
CMD echo "Executing CMD 2"

Si vous construisez cela dans une image et exécutez un conteneur dans cette image, alors, comme l'indique GingerBeer, seul le dernier CMD sera pris en compte. La sortie de ce conteneur sera donc:

Exécution de CMD 2

La façon dont je pense à cela est que "CMD" définit une seule variable globale pour l'image entière en cours de construction, donc les instructions "CMD" successives écrasent simplement toutes les écritures précédentes sur cette variable globale, et dans l'image finale qui est construite, la le dernier à écrire gagne. Puisqu'un Dockerfile s'exécute de haut en bas, nous savons que le CMD le plus bas est celui qui obtient cette "écriture" finale (métaphoriquement).

RUN: les commandes peuvent ne pas s'exécuter si les images sont mises en cache

Un point subtil à noter à propos de RUN est qu'il est traité comme une fonction pure même s'il y a des effets secondaires, et est donc mis en cache. Cela signifie que si RUN a eu des effets secondaires qui ne modifient pas l'image résultante et que cette image a déjà été mise en cache, la RUN ne sera pas exécutée à nouveau et les effets secondaires ne se produiront donc pas lors des générations suivantes. Par exemple, prenez ce Dockerfile:

FROM busybox
RUN echo "Just echo while you work"

La première fois que vous l'exécutez, vous obtiendrez une sortie comme celle-ci, avec différents ID alphanumériques:

docker build -t example/run-echo .
Sending build context to Docker daemon  9.216kB
Step 1/2 : FROM busybox
 ---> be5888e67be6
Step 2/2 : RUN echo "Just echo while you work"
 ---> Running in ed37d558c505
Just echo while you work
Removing intermediate container ed37d558c505
 ---> 6f46f7a393d8
Successfully built 6f46f7a393d8
Successfully tagged example/run-echo:latest

Notez que l'instruction echo a été exécutée ci-dessus. La deuxième fois que vous l'exécutez, il utilise le cache et vous ne verrez aucun écho dans la sortie de la build:

docker build -t example/run-echo .
Sending build context to Docker daemon  9.216kB
Step 1/2 : FROM busybox
 ---> be5888e67be6
Step 2/2 : RUN echo "Just echo while you work"
 ---> Using cache
 ---> 6f46f7a393d8
Successfully built 6f46f7a393d8
Successfully tagged example/run-echo:latest
Colm Bhandal
la source
1

Il y a eu suffisamment de réponses sur RUN et CMD . Je veux juste ajouter quelques mots sur ENTRYPOINT . Les arguments CMD peuvent être remplacés par des arguments de ligne de commande, tandis que les arguments ENTRYPOINT sont toujours utilisés.

Cet article est une bonne source d'informations.

Milo Lu
la source