Diferença entre RUN e CMD em um Dockerfile


Respostas:


425

RUN é uma etapa de criação da imagem, o estado do contêiner após um RUNcomando ser confirmado na imagem do contêiner. Um arquivo Docker pode ter várias RUNetapas que se sobrepõem para criar a imagem.

CMD é o comando que o contêiner executa por padrão quando você inicia a imagem criada. Um Dockerfile usará apenas a final CMDdefinida. O CMDpode ser substituído ao iniciar um contêiner com docker run $image $other_command.

ENTRYPOINT também está intimamente relacionado CMDe pode modificar a maneira como um contêiner inicia uma imagem.


15
você faz todo o RUNnecessário para configurar seu ambiente, e seu (apenas) CMD inicia o processo em execução em seu contêiner, por exemplo, para nginx, extraia de github.com/nginxinc/docker-nginx/blob/… você vê a linhaCMD ["nginx", "-g", "daemon off;"]
user2915097

"Um arquivo Dockerfile pode ter apenas um CMD" - não é tecnicamente verdadeiro, mas efetivamente todos, exceto um, serão ignorados. Veja a resposta do GingerBeer.
Colm Bhandal 19/04

"Um arquivo Dockerfile usará apenas o CMD final definido"? na verdade, o CMD final definido será usado no lançamento da imagem como um contêiner, certo?
paul cheung

1
Sim @paulcheung, o comando final no arquivo docker é gravado na imagem e é o comando que o contêiner executa por padrão quando você inicia a imagem criada.
Matt

126

RUN - comando dispara enquanto construímos a imagem do docker.

CMD - o comando é acionado enquanto lançamos a imagem do docker criada.


67

Achei este artigo muito útil para entender a diferença entre eles:

As instruções RUN - RUN permitem que você instale seu aplicativo e pacotes necessários para isso. Ele executa qualquer comando em cima da imagem atual e cria uma nova camada confirmando os resultados. Muitas vezes, você encontrará várias instruções RUN em um Dockerfile.

CMD - A instrução CMD permite definir um comando padrão, que será executado apenas quando você executar o contêiner sem especificar um comando. Se o contêiner do Docker for executado com um comando, o comando padrão será ignorado. Se o Dockerfile tiver mais de uma instrução CMD, todas as instruções, exceto a última,
serão ignoradas.


13

EXECUTAR - Instale o Python, seu contêiner agora tem o python gravado em sua imagem
CMD - python hello.py, execute seu script favorito


CMD - Instale o Python, meu contêiner agora não tem python queimado em sua imagem?
Carlos Fontes

RUN irá criar uma camada de imagem de python, CMD irá simplesmente executar o comando não criar a imagem
Rohit Salecha

8

Comando RUN: O comando RUN irá, basicamente, executar o comando padrão, quando estivermos construindo a imagem. Ele também confirmará as alterações na imagem para a próxima etapa.

Pode haver mais de um comando RUN, para auxiliar no processo de criação de uma nova imagem.

Comando do CMD: os comandos do CMD apenas definirão o comando padrão para o novo contêiner. Isso não será executado no momento da construção.

Se um arquivo docker tiver mais de 1 comando CMD, todos eles serão ignorados, exceto o último. Como este comando não executará nada, apenas definirá o comando padrão.



4

RUN : Pode ser muitos e é usado no processo de construção , por exemplo, instalar várias bibliotecas

CMD : pode ter apenas 1, que é o seu ponto inicial de execução (por exemplo ["npm", "start"], ["node", "app.js"])


2

As respostas existentes cobrem a maior parte do que qualquer pessoa que esteja olhando para essa pergunta precisaria. Então, abordarei algumas áreas de nicho para CMD e RUN.

CMD: duplicatas são permitidas, mas desperdiçam

O GingerBeer faz uma observação importante: você não receberá nenhum erro se colocar mais de um CMD - mas é um desperdício fazê-lo. Eu gostaria de elaborar com um exemplo:

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

Se você criar isso em uma imagem e executar um contêiner nessa imagem, como GingerBeer afirma, apenas o último CMD será atendido. Portanto, a saída desse contêiner será:

Executando o CMD 2

A maneira como penso é que "CMD" está definindo uma única variável global para toda a imagem que está sendo criada, de modo que sucessivas instruções "CMD" simplesmente substituem quaisquer gravações anteriores nessa variável global e, na imagem final criada, último a escrever vitórias. Como um Dockerfile é executado em ordem de cima para baixo, sabemos que o CMD mais baixo é aquele que obtém essa "gravação" final (metaforicamente falando).

EXECUÇÃO: comandos podem não executar se as imagens estiverem em cache

Um ponto sutil a ser observado sobre o RUN é que ele é tratado como uma função pura, mesmo que haja efeitos colaterais e, portanto, é armazenado em cache. O que isso significa é que, se o RUN tiver alguns efeitos colaterais que não alteram a imagem resultante e essa imagem já tiver sido armazenada em cache, o RUN não será executado novamente e, portanto, os efeitos colaterais não ocorrerão nas construções subseqüentes. Por exemplo, considere este Dockerfile:

FROM busybox
RUN echo "Just echo while you work"

Na primeira vez em que você o executa, você obtém resultados como este, com diferentes IDs alfanuméricos:

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

Observe que a instrução echo foi executada acima. Na segunda vez que você o executa, ele usa o cache e você não verá nenhum eco na saída da compilação:

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

1

Houve respostas suficientes no RUN e no CMD . Eu só quero adicionar algumas palavras no ENTRYPOINT . Os argumentos do CMD podem ser substituídos pelos argumentos da linha de comando, enquanto os argumentos ENTRYPOINT são sempre usados.

Este artigo é uma boa fonte de informações.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.