Diferença entre RUN e CMD em um Dockerfile

293

Estou confuso sobre quando devo usar CMDvs RUN. Por exemplo, para executar comandos bash / shell (ou seja ls -la), eu sempre usaria CMDou há uma situação em que usaria RUN? Tentando entender as melhores práticas sobre essas duas Dockerfilediretivas semelhantes .

TakeSoUp
fonte

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.

Matt
fonte
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.

Nisal Edu
fonte
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.

fay
fonte
13

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

Rohit Salecha
fonte
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.

Cerveja de gengibre
fonte
6

Nota: Não confunda RUN com CMD. RUN realmente executa um comando e confirma o resultado; O CMD não executa nada no momento da criação, mas especifica o comando pretendido para a imagem.

da referência do arquivo docker

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

Elsayed
fonte
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"])

Xin
fonte
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
Colm Bhandal
fonte
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.

Milo Lu
fonte