fbpx
Dockerfiles: Entrypoint vs CMD?
Publicado em: sábado, 6 de jun de 2020
Categorias: Docker de A a Z
Tags: Docker

Você viu Entrypoint e CMD em algum lugar, seja em um dockerfile ou em um docker run, mas não faz a ideia do que seja?

Vem comigo, é mais simples do que você imagina.

Esse é o típico cenário em que a resposta é mais idiota do que você possa imaginar. É algo que não é nem sofisticado, nem complexo, mas gera confusão.

Entrypoint e CMD só existem de forma separada para facilitar nossas vidas. Nada mais.

Quando um container é inicializado, o que será executado é a soma de Entrypoint e CMD.

Então em um dockerfile:

...
ENTRYPOINT ["dotnet", "suaapp.dll"] 
CMD ["meuparametro"]
...

O resultado da execução é semelhante a:

...
dotnet suaapp.dll meuparametro
...

Isso quer dizer que, se as 3 sentenças estivessem somente no Entrypoint ou somente no CMD, o resultado seria exatamente o mesmo? Sim!

“Se funciona, então estás certo!” Será?

Então podemos concluir que tanto faz usar CMD ou ENTRYPOINT? Não!

Estou contanto qual é o efeito prático. Você precisa entender agora pra que existe a divisão entre Entrypoint e CMD e pra que foram criados separados.

A anatomia do docker run

Essa é a anatomia de um docker run:

...
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
...

Nota que você enxerga um COMMAND, mas não enxerga o ENTRYPOINT?

Isso é feito para que o Entrypoint seja estático, definido na imagem, durante o build, enquanto o CMD, você teria um default no dockerfile, mas pode facilmente sobrescrever durante um docker run, por exemplo.

“O ENTRYPOINT de uma imagem é semelhante a um COMMAND porque especificam o executável a ser executado quando o contêiner é iniciado, mas é (intencionalmente) mais difícil de substituir.” Docker run reference

Você pode sobrescrever o entrypoint usando –entrypoint em um docker run, mas sobrescrever o command é mais prático, e possui diversos facilitadores.

O Entrypoint foi desenhado para ser estático (sem impedir a modificação) e o Command foi desenhado para ser uma parte mais dinâmica, com facilitadores para a sobrescrita (com um default expresso no dockerfile).

Exemplo

Em um dockerfile de uma aplicação .NET Core padrão.

  • O EntryPoint é ["dotnet","assembly.dll" ].
  • O CMD é null

Dessa forma, se usarmos o Dockerfile ou sobrescrevermos em qualquer outra oportunidade o CMD, esses parâmetros serão passados no argumento args do método Main da classe Program.

class Program
{
    static void Main(string[] args)
    {
        if (args != null && args.Length > 0)
            Console.WriteLine("Seus parâmetros " + args[0]);
        else
            Console.WriteLine("Sem parâmetros ");
    }
}
FROM ...

Entrypoint ["dotnet", "seuassembly.dll"]

CMD ["none"]

Na execução padrão, docker run imagem teríamos como output “none”.

Mas para ter como output o texto “teste” é basta executar docker run imagem teste.

Claro que o exemplo foi ridículo e simples, no entanto esse é um recurso poderoso.

Testa aí!?!

Te ajudou?

Quando eu pensei nisso pela primeira vez, tentei achar algo relevante, mas cheguei na documentação a explicações muito simplistas. Eu queria achar um bom e fantástico motivo. Na verdade depois de entender o propósito eu acho de fato sofisticado, principalmente pela simplicidade.

Você sabia disso? Te ajudou?

Compartilha com alguém que possa ser ajudado também!

1 Comentário

  1. Fernando

    Sensacional! Muitíssimo obrigado! Finalmente entendi!

    Responder

Enviar um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.

[docker de a a z]

Lives

Fique de olho nas lives

Fique de olho nas lives no meu canal do Youtube, no Canal .NET e nos Grupos do Facebook e Instagram.

Aceleradores

Existem diversas formas de viabilizar o suporte ao teu projeto. Seja com os treinamentos, consultoria, mentorias em grupo.