Usando ENTRYPOINT vs CMD no Dockerfile
No Docker, existem duas instruções para especificar qual comando deve ser executado quando um container é iniciado: CMD e ENTRYPOINT. Elas têm propósitos e comportamentos diferentes, e entender a diferença é importante para o gerenciamento de containers.
Entendendo ENTRYPOINT e CMD
ENTRYPOINT: Define o executável que será executado quando o container for iniciado. É mais difícil de substituir em tempo de execução.
CMD: Fornece argumentos padrão para o ENTRYPOINT ou pode especificar todo o comando se o ENTRYPOINT não for usado. É fácil de substituir em tempo de execução.
Vamos explorar a diferença criando dois Dockerfiles diferentes.
Primeiro, crie um novo script Python que aceite argumentos de linha de comando:
nano greeting.py
Adicione o seguinte código:
import sys
print("Script started!")
if len(sys.argv) > 1:
print(f"Arguments provided: {sys.argv[1:]}")
for arg in sys.argv[1:]:
print(f"- {arg}")
else:
print("No arguments provided.")
print("Script finished!")
Salve e saia do nano.
Agora, vamos criar um Dockerfile que usa CMD:
nano Dockerfile.cmd
Adicione o seguinte conteúdo:
FROM python:3.9-slim
WORKDIR /app
COPY greeting.py .
CMD ["python", "greeting.py", "default", "arguments"]
Salve e saia do nano.
Construa a imagem:
docker build -t python-cmd -f Dockerfile.cmd .
Agora, crie outro Dockerfile que usa ENTRYPOINT:
nano Dockerfile.entrypoint
Adicione o seguinte conteúdo:
FROM python:3.9-slim
WORKDIR /app
COPY greeting.py .
ENTRYPOINT ["python", "greeting.py"]
CMD ["default", "arguments"]
Salve e saia do nano.
Construa a imagem:
docker build -t python-entrypoint -f Dockerfile.entrypoint .
Testando CMD vs ENTRYPOINT
Vamos executar containers de ambas as imagens e observar as diferenças.
Primeiro, execute um container usando a imagem CMD sem argumentos adicionais:
docker run --name cmd-container python-cmd
A saída deve ser semelhante a:
Script started!
Arguments provided: ['default', 'arguments']
- default
- arguments
Script finished!
Agora, execute um container com a imagem CMD, mas forneça argumentos personalizados:
docker run --name cmd-container-custom python-cmd hello world
Saída:
Script started!
No arguments provided.
Script finished!
Observe que todo o comando foi substituído por hello world, que não são passados como argumentos para o nosso script.
Agora, vamos executar um container usando a imagem ENTRYPOINT sem argumentos adicionais:
docker run --name entrypoint-container python-entrypoint
Saída:
Script started!
Arguments provided: ['default', 'arguments']
- default
- arguments
Script finished!
Finalmente, execute um container com a imagem ENTRYPOINT e forneça argumentos personalizados:
docker run --name entrypoint-container-custom python-entrypoint hello world
Saída:
Script started!
Arguments provided: ['hello', 'world']
- hello
- world
Script finished!
Desta vez, nossos argumentos são passados corretamente para o script Python porque ENTRYPOINT define o executável, e quaisquer argumentos adicionais fornecidos para docker run são passados para esse executável.
Melhores Práticas
- Use
ENTRYPOINT para containers que sempre devem executar um comando específico (como nosso script Python)
- Use
CMD para fornecer argumentos padrão que podem ser facilmente substituídos
- Combine ambos usando
ENTRYPOINT para o comando e CMD para argumentos padrão
Limpe os containers:
docker rm cmd-container cmd-container-custom entrypoint-container entrypoint-container-custom
Você agora aprendeu a diferença entre CMD e ENTRYPOINT no Docker, o que é essencial para controlar como seus scripts Python são executados quando um container é iniciado.