Curso Docker - 17. Diferencias entre CMD y ENTRYPOINT en Docker

Existen dos directivas en Dockerfile para especificar qué comando se va a ejecutar por defecto cuando generemos las imágenes Docker: CMD y ENTRYPOINT.

Una explicación sencilla para ver sus diferencias es que si únicamente especificamos CMD, el ENTRYPOINT será el predeterminado, es decir, /bin/bash -c. Si se utilizan ambos, entonces el ENTRYPOINT especifica el ejecutable del proceso contenedor y CMD se utilizará como los parámetros de dicho ejecutable.

Vamos a ver un ejemplo:

FROM ubuntu:18.04

En este caso, se está utilizando el ENTRYPOINT predeterminado, es decir, /bin/bash -c. Especificando el CMD como date, lo que estaremos ejecutando es /bin/bash -c date.

Ahora vamos a ejecutar los comandos:

$ docker build -t test .
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM ubuntu:18.04
 ---> d131e0fa2585
Step 2/2 : CMD ["date"]
 ---> Running in a7c7815468f3
Removing intermediate container a7c7815468f3
 ---> 60c6d1a8974c
Successfully built 60c6d1a8974c
Successfully tagged test:latest
$ docker run test
Fri May 10 16:46:41 UTC 2019

La directiva CMD puede modificarse a la hora de hacer el docker run, y en este caso se utilizará el parámetro que le vamos a pasar:

docker run test hostname

Si especificamos la directiva ENTRYPOINT, Docker utilizará ese ejecutable y CMD serán los parámetros:

FROM ubuntu:18.04

Si volvemos a generar la imagen y ejecutar un contenedor Docker:

$ docker build -t test .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM ubuntu:18.04
 ---> d131e0fa2585
Step 2/3 : ENTRYPOINT ["echo"]
 ---> Running in 6238c28a1258
Removing intermediate container 6238c28a1258
 ---> bfde3b8fac6e
Step 3/3 : CMD ["Curso de Docker en Geeky Theory"]
 ---> Running in 62e60fbb2f14
Removing intermediate container 62e60fbb2f14
 ---> 1bf7c1314bb3
Successfully built 1bf7c1314bb3
Successfully tagged test:latest
$ docker run test
Curso de Docker en Geeky Theory

Podemos sobrescribir también el CMD:

$ docker run test Hola
Hola

Y además, también podemos pasar el ENTRYPOINT como parámetro con --entrypoint:

docker run --entrypoint=hostname test