Introducción
Un aspecto fundamental en el momento de crear nuevas imágenes es entender la diferencia entre ENTRYPOINT y CMD en Docker.
Estas dos instrucciones son muy similares y siempre hay mucha confusión.
Por suerte, Docker dispone de una documentación muy amplia para cualquier duda que nos surja. En anteriores posts hemos visto como instalar Docker en Ubuntu 20.04 o instalar Docker compose.
En este artículo, veremos las diferencias entre las dos instrucciones. ¿Qué son? ¿Y cuándo usar cada uno?
1. CMD
Para entender el concepto en profundidad, vamos a crear un Dockerfile que contenga una instrucción CMD:
From ubuntu:20.04
CMD ["echo", "Hola ejecutado desde CMD"]
A continuación, guardamos el contenido en un fichero Dockerfile y construimos una imagen llamada «pruebas«:
docker build . -t pruebas
La ejecución del comando anterior ha proporcionado la siguiente salida:
Esta salida se produce porque en la definición del Dockerfile hemos incluido como última instrucción CMD que al ejecutar el contenedor la muestra en la salida de consola.
Vamos a modificar la forma en la que ejecutamos el contenedor para observar lo que ocurre añadiendo como último parámetro «Hola desde el CLI«:
docker run pruebas echo Hola desde el CLI
Y obtenemos la siguiente salida:
En el output lo que podemos ver es que el comando proporcionado en la ejecución de docker run ha reemplazado el comando que estaba definido en el archivo Dockerfile.
El resultado de la ejecución anterior nos lleva a la conclusión que si definimos la instrucción CMD como la última instrucción en nuestro archivo Dockerfile será reemplazada por la que proporcionemos en la ejecución del contenedor a través del comando docker run.
2. ENTRYPOINT
Para ver la diferencia con el comando CMD vamos a sobreescribir el fichero Dockerfile, reemplazando el comando CMD por ENTRYPOINT:
From ubuntu:20.04
ENTRYPOINT ["echo","Hola desde ENTRYPOINT"]
Generamos la imagen con el comando que hemos visto anteriormente:
docker build . -t pruebas
Y vemos que esta vez la salida que genera el comando es:
Ahora creamos un nuevo contenedor pasándole el mismo parámetro que hemos ejecutado anteriormente (Hola desde Docker CLI) para ver qué salida nos proporciona:
docker run pruebas echo Hola desde Docker CLI
Y vemos que la salida es ligeramente diferente a la que hemos obtenido usando el comando CMD.
Lo que podemos ver en esta salida es que contiene las instrucciones definidas en el ENTRYPOINT y la que le hemos pasado por parámetro al crear el contenedor.
Es decir, ha ejecutado primero las instrucciones definidas en el ENTRYPOINT y luego la que le hemos pasado por parámetro en la creación del contenedor.
Si usamos ENTRYPOINT en Dockerfile y también pasamos la instrucción CMD en la creación del contenedor, entonces el punto de entrada no se ignora, sino que las instrucciones CMD se agregan al ENTRYPOINT como argumentos.
3. Conclusión
El artículo ha mostrado la diferencia entre Entrypoint y CMD en Docker. El uso de cada una depende de la necesidad que tengamos al crear la imagen.
Pero en general, podemos decir:
ENTRYPOINT: Se usa cuando necesitamos que las instrucciones siempre sean ejecutadas.
CMD: Se usa cuando necesitamos ejecutar un comando predeterminado al crear el contenedor, pero que pueda ser anulado si se le pasa otra instrucción al ejecutar el comando docker run.