Uso de ENTRYPOINT vs CMD en Dockerfile
En Docker, hay dos instrucciones para especificar qué comando debe ejecutarse cuando se inicia un contenedor: CMD y ENTRYPOINT. Tienen diferentes propósitos y comportamientos, y comprender la diferencia es importante para la gestión de contenedores.
Entendiendo ENTRYPOINT y CMD
ENTRYPOINT: Define el ejecutable que se ejecutará cuando se inicie el contenedor. Es más difícil de anular en tiempo de ejecución.
CMD: Proporciona argumentos predeterminados para el ENTRYPOINT o puede especificar todo el comando si no se usa ENTRYPOINT. Es fácil de anular en tiempo de ejecución.
Exploremos la diferencia creando dos Dockerfiles diferentes.
Primero, cree un nuevo script de Python que acepte argumentos de línea de comandos:
nano greeting.py
Agregue el siguiente 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!")
Guarde y salga de nano.
Ahora, creemos un Dockerfile que use CMD:
nano Dockerfile.cmd
Agregue el siguiente contenido:
FROM python:3.9-slim
WORKDIR /app
COPY greeting.py .
CMD ["python", "greeting.py", "default", "arguments"]
Guarde y salga de nano.
Construya la imagen:
docker build -t python-cmd -f Dockerfile.cmd .
Ahora, cree otro Dockerfile que use ENTRYPOINT:
nano Dockerfile.entrypoint
Agregue el siguiente contenido:
FROM python:3.9-slim
WORKDIR /app
COPY greeting.py .
ENTRYPOINT ["python", "greeting.py"]
CMD ["default", "arguments"]
Guarde y salga de nano.
Construya la imagen:
docker build -t python-entrypoint -f Dockerfile.entrypoint .
Probando CMD vs ENTRYPOINT
Ejecutemos contenedores desde ambas imágenes y observemos las diferencias.
Primero, ejecute un contenedor usando la imagen CMD sin argumentos adicionales:
docker run --name cmd-container python-cmd
La salida debería ser similar a:
Script started!
Arguments provided: ['default', 'arguments']
- default
- arguments
Script finished!
Ahora, ejecute un contenedor con la imagen CMD pero proporcione argumentos personalizados:
docker run --name cmd-container-custom python-cmd hello world
Salida:
Script started!
No arguments provided.
Script finished!
Observe que todo el comando fue reemplazado con hello world, que no se pasan como argumentos a nuestro script.
Ahora, ejecutemos un contenedor usando la imagen ENTRYPOINT sin argumentos adicionales:
docker run --name entrypoint-container python-entrypoint
Salida:
Script started!
Arguments provided: ['default', 'arguments']
- default
- arguments
Script finished!
Finalmente, ejecute un contenedor con la imagen ENTRYPOINT y proporcione argumentos personalizados:
docker run --name entrypoint-container-custom python-entrypoint hello world
Salida:
Script started!
Arguments provided: ['hello', 'world']
- hello
- world
Script finished!
Esta vez, nuestros argumentos se pasan correctamente al script de Python porque ENTRYPOINT define el ejecutable, y cualquier argumento adicional proporcionado a docker run se pasa a ese ejecutable.
Mejores Prácticas
- Use
ENTRYPOINT para contenedores que siempre deben ejecutar un comando específico (como nuestro script de Python)
- Use
CMD para proporcionar argumentos predeterminados que se pueden anular fácilmente
- Combine ambos usando
ENTRYPOINT para el comando y CMD para los argumentos predeterminados
Limpie los contenedores:
docker rm cmd-container cmd-container-custom entrypoint-container entrypoint-container-custom
Ahora ha aprendido la diferencia entre CMD y ENTRYPOINT en Docker, lo cual es esencial para controlar cómo se ejecutan sus scripts de Python cuando se inicia un contenedor.