¿Cuál es la diferencia entre CMD y ENTRYPOINT en un Dockerfile?

2113

En Dockerfiles hay dos comandos que se parecen a mí: CMDy ENTRYPOINT. Pero supongo que hay una diferencia (¿sutil?) Entre ellos; de lo contrario, no tendría ningún sentido tener dos comandos para la misma cosa.

Los estados de documentación para CMD

The main purpose of a CMD is to provide defaults for an executing container.

y para ENTRYPOINT:

An ENTRYPOINT helps you to configure a container that you can run as an executable.

Entonces, ¿cuál es la diferencia entre esos dos comandos?

5
2098

Docker tiene un punto de entrada predeterminado que es, /bin/sh -cpero no tiene, un comando predeterminado.

Cuando ejecuta docker run -i -t ubuntu bash la ventana acoplable de esta manera: el punto de entrada es el predeterminado /bin/sh -c, la imagen es ubuntuy el comando es bash.

El comando se ejecuta a través del punto de entrada. es decir, lo que realmente se ejecuta es /bin/sh -c bash. Esto permitió que Docker se implementara RUNrápidamente confiando en el analizador del shell.

Más tarde, la gente les pide que sean capaces de personalizar esto, así ENTRYPOINTy --entrypointse introdujeron.

Todo lo que ubuntusigue en el ejemplo anterior es el comando y se pasa al punto de entrada. Al usar la CMDinstrucción, es exactamente como si lo estuviera haciendo docker run -i -t ubuntu <cmd>. <cmd>será el parámetro del punto de entrada.

También obtendrá el mismo resultado si escribe este comando docker run -i -t ubuntu. Aún iniciará un shell bash en el contenedor debido a que ubuntu Dockerfile especificó una CMD predeterminada:CMD ["bash"]

Como todo se pasa al punto de entrada, puedes tener un comportamiento muy agradable de tus imágenes. El ejemplo de @Jiri es bueno, muestra cómo usar una imagen como "binario". Cuando se usa ["/bin/cat"]como punto de entrada y luego lo hace docker run img /etc/passwd, lo obtiene, /etc/passwdes el comando y se pasa al punto de entrada, por lo que la ejecución del resultado final es simple /bin/cat /etc/passwd.

Otro ejemplo sería tener cualquier cli como punto de entrada. Por ejemplo, si usted tiene una imagen de Redis, en lugar de correr docker run redisimg redis -H something -u toto get key, sólo tiene que tener ENTRYPOINT ["redis", "-H", "something", "-u", "toto"]y luego ejecutar así por el mismo resultado: docker run redisimg get key.

14
  • 5
    Para nada. ENTRYPOINT establece un metadato que puede (pero puede ser anulado) en tiempo de ejecución, por lo que si no cambia nada, después de iniciar su contenedor, el resultado será el mismo, sin embargo, RUN se ejecutará en el momento de la compilación y sin importar lo que usted hacer en tiempo de ejecución, estará aquí. creack 29/12/15 a las 15:07
  • 12
    Por defecto no hay ENTRYPOINT; si se utiliza un shell depende de la forma utilizada del CMDcomando ( docs.docker.com/engine/reference/builder/#cmd ). Blaisorblade 13/01/16 a las 22:29
  • 47
    Gracias por esto, el contexto histórico ayuda mucho ya que estaba luchando por recordar las reglas aparentemente arcanas sobre lo que se anula y lo que se agrega, etc. Un punto útil para los escritores de documentación técnica en todas partes: ayudar al lector a construir un modelo mental del sistema, no se limite a enumerar hechos y escenarios :-)ashirley 9 de mayo de 2016 a las 13:32
  • 123
    Esta es una respuesta fabulosa. Creo que la documentación del estibador debe agregar esta bajo una sección llamada CMDvs ENTRYPOINT. Tarik 28/12/2016 a las 19:37
  • 6
    @Webman No. Son dos instrucciones diferentes. Si ambos existen, CMD se trataría como parámetros de ENTRYPOINT. Light.G 24 de septiembre de 2018 a las 16:14
829

Las ENTRYPOINTespecifica un comando que siempre se ejecuta cuando se inicia el contenedor.

Los CMDargumentos especifica que se alimentará a la ENTRYPOINT.

Si desea hacer una imagen dedicada a un comando específico, utilizará ENTRYPOINT ["/path/dedicated_command"]

De lo contrario, si desea crear una imagen para fines generales, puede dejarla sin ENTRYPOINTespecificar y usarla, CMD ["/path/dedicated_command"]ya que podrá anular la configuración proporcionando argumentos a docker run.

Por ejemplo, si su Dockerfile es:

FROM debian:wheezy
ENTRYPOINT ["/bin/ping"]
CMD ["localhost"]

Ejecutar la imagen sin ningún argumento hará ping al localhost:

$ docker run -it test
PING localhost (127.0.0.1): 48 data bytes
56 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.096 ms
56 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.088 ms
56 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.088 ms
^C--- localhost ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.088/0.091/0.096/0.000 ms

Ahora, ejecutar la imagen con un argumento hará ping al argumento:

$ docker run -it test google.com
PING google.com (173.194.45.70): 48 data bytes
56 bytes from 173.194.45.70: icmp_seq=0 ttl=55 time=32.583 ms
56 bytes from 173.194.45.70: icmp_seq=2 ttl=55 time=30.327 ms
56 bytes from 173.194.45.70: icmp_seq=4 ttl=55 time=46.379 ms
^C--- google.com ping statistics ---
5 packets transmitted, 3 packets received, 40% packet loss
round-trip min/avg/max/stddev = 30.327/36.430/46.379/7.095 ms

A modo de comparación, si su Dockerfile es:

FROM debian:wheezy
CMD ["/bin/ping", "localhost"]

Ejecutar la imagen sin ningún argumento hará ping al localhost:

$ docker run -it test
PING localhost (127.0.0.1): 48 data bytes
56 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.076 ms
56 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.087 ms
56 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.090 ms
^C--- localhost ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.076/0.084/0.090/0.000 ms

Pero ejecutar la imagen con un argumento ejecutará el argumento:

docker run -it test bash
[email protected]:/#

Consulte este artículo de Brian DeHamer para obtener aún más detalles: https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd/

6
  • 314
    The ENTRYPOINT specifies a command that will always be executed when the container starts. The CMD specifies arguments that will be fed to the ENTRYPOINT.es un buen resumen al grano. Jingguo Yao 4 de ene. De 2016 a las 14:26
  • 4
    ENTRYPOINT también se puede anular usando el indicador --entrypoint. por ejemplo, docker run -it --entrypoint bash testseenimurugan 4 de septiembre de 2018 a las 16:15
  • 4
    Me gustan tus ejemplos, ¡es realmente útil! Chau Giang 16 de agosto de 2019 a las 4:53
  • 2
    @Jingguo Yao: ¿Qué pasa si CMD contiene un comando como - CMD ["nginx", "- g", "daemon", "off"]? ¿Estaría encadenado? KMC 29/08/19 a las 16:00
  • 1
    ENTRYPOINTa menudo se apunta a un script de entrada (en lugar de un comando) que puede hacer muchas cosas útiles como: verificar los requisitos antes de la ejecución (como sondeos de preparación en dependencias); proxy / envolver un comando para validarlo, o para cambiar el usuario que está ejecutando, o al propietario archivos de cambios (por ejemplo, cuando se monta hostPathen Minikube, por defecto los archivos se redefinen con UID / GID 1000:1000 ), etc ..Kamafeather 9/11/20 a las 20:56
301

Según los documentos de Docker ,

Both CMD and ENTRYPOINT instructions define what command gets executed when running a container. There are few rules that describe their co-operation.

  1. Dockerfile should specify at least one of CMD or ENTRYPOINT commands.
  2. ENTRYPOINT should be defined when using the container as an executable.
  3. CMD should be used as a way of defining default arguments for an ENTRYPOINT command or for executing an ad-hoc command in a container.
  4. CMD will be overridden when running the container with alternative arguments.

Las tablas siguientes muestran qué comando se ejecuta para diferentes ENTRYPOINT/ CMDcombinaciones :

- No ENTRYPOINT

╔════════════════════════════╦═════════════════════════════╗
║ No CMD                     ║ error, not allowed          ║
╟────────────────────────────╫─────────────────────────────╢
║ CMD ["exec_cmd", "p1_cmd"] ║ exec_cmd p1_cmd             ║
╟────────────────────────────╫─────────────────────────────╢
║ CMD ["p1_cmd", "p2_cmd"]   ║ p1_cmd p2_cmd               ║
╟────────────────────────────╫─────────────────────────────╢
║ CMD exec_cmd p1_cmd        ║ /bin/sh -c exec_cmd p1_cmd  ║
╚════════════════════════════╩═════════════════════════════╝

- ENTRYPOINT exec_entry p1_entry

╔════════════════════════════╦══════════════════════════════════╗
║ No CMD                     ║ /bin/sh -c exec_entry p1_entry   ║
╟────────────────────────────╫──────────────────────────────────╢
║ CMD ["exec_cmd", "p1_cmd"] ║ /bin/sh -c exec_entry p1_entry   ║
╟────────────────────────────╫──────────────────────────────────╢
║ CMD ["p1_cmd", "p2_cmd"]   ║ /bin/sh -c exec_entry p1_entry   ║
╟────────────────────────────╫──────────────────────────────────╢
║ CMD exec_cmd p1_cmd        ║ /bin/sh -c exec_entry p1_entry   ║
╚════════════════════════════╩══════════════════════════════════╝

- ENTRYPOINT ["exec_entry", "p1_entry"]

╔════════════════════════════╦═════════════════════════════════════════════════╗
║ No CMD                     ║ exec_entry p1_entry                             ║
╟────────────────────────────╫─────────────────────────────────────────────────╢
║ CMD ["exec_cmd", "p1_cmd"] ║ exec_entry p1_entry exec_cmd p1_cmd             ║
╟────────────────────────────╫─────────────────────────────────────────────────╢
║ CMD ["p1_cmd", "p2_cmd"]   ║ exec_entry p1_entry p1_cmd p2_cmd               ║
╟────────────────────────────╫─────────────────────────────────────────────────╢
║ CMD exec_cmd p1_cmd        ║ exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd  ║
╚════════════════════════════╩═════════════════════════════════════════════════╝
9
  • 1
    @ Danielo515 Tanto 'px_cmd' como 'exec_entry' son solo cadenas ficticias aquí. Puede notar que /bin/sh -cse agregaría a CMD como prefijo mientras CMD está escrito en sintaxis ejecutable (no en sintaxis de lista). Light.G 26/09/18 a las 11:25
  • 1
    @royki Si el usuario especifica argumentos para ejecutar la ventana acoplable , anulará el valor predeterminado especificado en CMD. ron_g 31/07/19 a las 10:14
  • 3
    ENTRYPOINT exec_entry p1_entfue explicado erróneamente. El formulario de shell evita que se utilicen argumentos de línea de comandos de ejecución o CMD - docs.docker.com/engine/reference/builder/#entrypointMariusz Miesiak 18/11/19 a las 10:40
  • 2
    @MariuszMiesiak ya está actualizado. Gracias por tus comentarios. Rafaf Tahsin 22/11/19 a las 5:28
  • 2
    Por cierto: ¡esta respuesta definitivamente debería ser la respuesta aceptada! (mientras que el actual afirma que "Docker tiene un punto de entrada predeterminado que es /bin/sh -c" ...)ErikMD 12 de enero a las 20:13
186

Sí, esa es una buena pregunta. No lo entiendo completamente todavía, pero:

Entiendo que ENTRYPOINTes el binario que se está ejecutando. Puede anular el punto de entrada mediante --entrypoint = "".

docker run -t -i --entrypoint="/bin/bash" ubuntu

CMD es el argumento predeterminado del contenedor. Sin punto de entrada, el argumento predeterminado es el comando que se ejecuta. Con entrypoint, cmd se pasa a entrypoint como argumento. Puede emular un comando con punto de entrada.

# no entrypoint
docker run ubuntu /bin/cat /etc/passwd

# with entry point, emulating cat command
docker run --entrypoint="/bin/cat" ubuntu /etc/passwd

Entonces, la principal ventaja es que con el punto de entrada puede pasar argumentos (cmd) a su contenedor. Para lograr esto, necesita usar ambos:

# Dockerfile
FROM ubuntu
ENTRYPOINT ["/bin/cat"]

y

docker build -t=cat .

entonces puedes usar:

docker run cat /etc/passwd
#              ^^^^^^^^^^^
#                   CMD
#          ^^^      
#          image (tag)- using the default ENTRYPOINT
1
  • @Blauhirn En su caso, debe agregar argumentos a CMD en la sintaxis de lista y asegurarse de que el punto de entrada que ha especificado pueda analizar sus argumentos en CMD. Por lo general, agrego un argumento '-h' al punto de entrada. Entonces puedo ejecutar docker run image_name -hpara mostrar información de ayuda de esta imagen. Light.G 26 de sep. De 2018 a las 11:30
59

Agregaré mi respuesta como un ejemplo 1 que podría ayudarlo a comprender mejor la diferencia.

Supongamos que queremos crear una imagen que siempre ejecutará un comando de suspensión cuando se inicie. Crearemos nuestra propia imagen y especificaremos un nuevo comando:

FROM ubuntu
CMD sleep 10

Construyendo la imagen:

docker build -t custom_sleep .
docker run custom_sleep
# sleeps for 10 seconds and exits

¿Y si queremos cambiar el número de segundos? Tendríamos que cambiar el Dockerfileya que el valor está codificado allí, o anular el comando proporcionando uno diferente:

docker run custom_sleep sleep 20

Si bien esto funciona, no es una buena solución, ya que tenemos un comando de "suspensión" redundante. ¿Por qué redundante? Debido a que el único propósito del contenedor es dormir , tener que especificar el sleepcomando explícitamente es un poco incómodo.

Ahora intentemos usar la ENTRYPOINTinstrucción:

FROM ubuntu
ENTRYPOINT sleep

Esta instrucción especifica el programa que se ejecutará cuando se inicie el contenedor .

Ahora podemos ejecutar:

docker run custom_sleep 20

¿Qué pasa con un valor predeterminado? Bueno, lo has adivinado bien:

FROM ubuntu
ENTRYPOINT ["sleep"]
CMD ["10"]

El ENTRYPOINTes el programa que se ejecutará y el valor pasado al contenedor se le agregará.

El ENTRYPOINTpuede ser anulado por la especificación de una --entrypointbandera, seguido por el nuevo punto de entrada que desea utilizar.

No es mío, una vez vi un tutorial que proporcionaba este ejemplo

4
  • 3
    Aquí hay un enlace al tutorial: youtu.be/OYbEWUbmk90 . Puede ser útil para futuros usuarios. ChiPlusPlus 16/11/19 a las 10:16
  • 2
    ¡Gracias! Esta explicación con el ejemplo fue mucho más clara para mí (un principiante en la ventana acoplable) que la respuesta aceptada. typoerrpr 1 nov.20 a las 10:30
  • 1
    Creo que esta respuesta es la mejor. Para mí, como novato en Docker, es mucho más claro que el resto de las respuestas. Rodyb 29 de julio a las 15:31
  • La mejor explicación que pude encontrar en una web. ¡Muchas gracias! vitali_li 26 de agosto a las 19:01
59

Diferencia entre CMD y ENTRYPOINT por intuición :

  • ENTRYPOINT: comando para ejecutar cuando se inicia el contenedor.
  • CMD: comando para ejecutar cuando se inicia el contenedor o argumentos para ENTRYPOINT si se especifica.

Sí, es confuso.

Puede anular cualquiera de ellos cuando ejecute Docker Run.

Diferencia entre CMD y ENTRYPOINT por ejemplo :

docker run -it --rm yourcontainer /bin/bash            <-- /bin/bash overrides CMD
                                                       <-- /bin/bash does not override ENTRYPOINT
docker run -it --rm --entrypoint ls yourcontainer      <-- overrides ENTRYPOINT with ls
docker run -it --rm --entrypoint ls yourcontainer  -la  <-- overrides ENTRYPOINT with ls and overrides CMD with -la

Más sobre la diferencia entre CMDy ENTRYPOINT:

Un argumento docker runcomo / bin / bash anula cualquier comando CMD que escribimos en Dockerfile.

ENTRYPOINT no se puede anular en tiempo de ejecución con comandos normales como docker run [args]. Los argsal final de docker run [args]se proporcionan como argumentos para ENTRYPOINT. De esta manera podemos crear un containerque es como un binario normal como ls.

Entonces CMD puede actuar como parámetros predeterminados para ENTRYPOINT y luego podemos anular los argumentos de CMD de [args].

ENTRYPOINT se puede anular con --entrypoint.

58

En una palabra:

  • CMD establece el comando y / o los parámetros predeterminados, que se pueden sobrescribir desde la línea de comando cuando se ejecuta el contenedor de la ventana acoplable.
  • El comando y los parámetros de ENTRYPOINT no se sobrescribirán desde la línea de comandos. En su lugar, todos los argumentos de la línea de comando se agregarán después de los parámetros ENTRYPOINT.

Si necesita más detalles o le gustaría ver la diferencia en un ejemplo, hay una publicación de blog que compara de manera integral CMD y ENTRYPOINT con muchos ejemplos: http://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/

0
28

Hay algunas buenas respuestas para ello. Quiero explicarlo a través de una demostración por Doc.

  • CMD define comandos y / o parámetros predeterminados para un contenedor. CMD es una instrucción que es mejor usar si necesita un comando predeterminado que los usuarios pueden anular fácilmente. Si un Dockerfile tiene varias CMD, solo aplica las instrucciones de la última.
  • ENTRYPOINT se prefiere cuando desea definir un contenedor con un ejecutable específico.

No puede anular un ENTRYPOINT al iniciar un contenedor a menos que agregue la  --entrypoint bandera.

  1. CMD

Archivo Docker

  FROM centos:8.1.1911

  CMD ["echo", "Hello Docker"]

Resultado de la ejecución

$ sudo docker run <image-id>
Hello Docker
$ sudo docker run <image-id> hostname   # hostname is exec to override CMD
244be5006f32
  1. PUNTO DE ENTRADA

Archivo Docker

  FROM centos:8.1.1911

  ENTRYPOINT ["echo", "Hello Docker"]

Resultado de la ejecución

$ sudo docker run <image-id>
Hello Docker
$ sudo docker run <image-id> hostname   # hostname as parameter to exec
Hello Docker hostname
  1. Hay muchas situaciones en las que combinar CMD y ENTRYPOINT sería la mejor solución para su contenedor Docker. En tales casos,  el ejecutable se define con ENTRYPOINT, mientras que CMD especifica el parámetro predeterminado.

Archivo Docker

  FROM centos:8.1.1911

  ENTRYPOINT ["echo", "Hello"]
  CMD ["Docker"]

Resultado de la ejecución

$ sudo docker run <image-id>
Hello Docker
$ sudo docker run <image-id> Ben
Hello Ben
20

La respuesta aceptada es fabulosa para explicar la historia. Encuentro que esta tabla lo explica muy bien del documento oficial sobre 'cómo interactúan CMD y ENTRYPOINT' : ingrese la descripción de la imagen aquí

13

Me encontré con esto y al principio me pareció realmente confuso para ser honesto y creo que esta confusión proviene de usar la palabra "CMD" porque, de hecho, lo que va allí actúa como argumento . Entonces, después de investigar un poco, entendí cómo funciona. Básicamente:

ENTRYPOINT -> lo que especifique aquí sería el comando que se ejecutará cuando se inicie el contenedor. Si omite esta definición, la ventana acoplable utilizará /bin/sh -c bashpara ejecutar su contenedor.

CMD -> estos son los argumentos agregados al ENTRYPOINT a menos que el usuario especifique algún argumento personalizado, es decir: docker run ubuntu <custom_cmd>en este caso, en lugar de agregar lo que se especifica en la imagen en la sección CMD, la ventana acoplable se ejecutará ENTRYPOINT <custom_cmd>. En caso de que no se haya especificado ENTRYPOINT, lo que vaya aquí se pasará a /bin/sh -cactuar de hecho como el comando a ejecutar al iniciar el contenedor.

Como todo, es mejor explicar lo que está pasando con ejemplos. Entonces, digamos que creo una imagen de Docker simple usando la siguiente especificación Dockerfile :

From ubuntu
ENTRYPOINT ["sleep"]

Luego lo construyo ejecutando lo siguiente:

docker build . -t testimg

Esto creará un contenedor que, cada vez que lo ejecutes, duerme. Entonces, si lo ejecuto de la siguiente manera:

docker run testimg

Obtendré lo siguiente:

sleep: missing operand
Try 'sleep --help' for more information.

Esto sucede porque el punto de entrada es el comando "dormir" que necesita un argumento. Entonces, para solucionar esto, solo proporcionaré la cantidad para dormir:

docker run testimg 5

Esto funcionará correctamente y como consecuencia el contenedor funcionará, duerme 5 segundos y sale. Como podemos ver en este ejemplo, la ventana acoplable simplemente agregó lo que va después del nombre de la imagen al binario del punto de entrada docker run testimg <my_cmd>. ¿Qué sucede si queremos pasar un valor predeterminado (argumento predeterminado) al punto de entrada? en este caso solo necesitamos especificarlo en la sección CMD , por ejemplo:

From ubuntu
ENTRYPOINT ["sleep"]
CMD ["10"]

En este caso, si el usuario no pasa ningún argumento, el contenedor usará el valor predeterminado (10) y lo pasará al punto de entrada sleep.

Ahora usemos solo CMD y omitamos la definición de ENTRYPOINT:

FROM ubuntu
CMD ["sleep", "5"]

Si reconstruimos y ejecutamos esta imagen, básicamente duerme durante 5 segundos.

Entonces, en resumen, puede usar ENTRYPOINT para que su contenedor actúe como un ejecutable. Puede usar CMD para proporcionar argumentos predeterminados a su punto de entrada o para ejecutar un comando personalizado al iniciar su contenedor que puede ser anulado desde afuera por el usuario.

8

Comentarios sobre la función EntryPoint en el código

// ENTRYPOINT /usr/sbin/nginx.

// Set the entrypoint (which defaults to sh -c) to /usr/sbin/nginx.

// Will accept the CMD as the arguments to /usr/sbin/nginx.

Otra referencia de documentos

You can use the exec form of ENTRYPOINT to set fairly stable default commands and arguments and then use CMD to set additional defaults that are more likely to be changed.

Ejemplo:

FROM ubuntu:14.04.3
ENTRYPOINT ["/bin/ping"]
CMD ["localhost", "-c", "2"]

Construir : sudo ventana acoplable acumulación -t ent_cmd.

CMD arguments are easy to override.

NO argument (sudo docker -it ent_cmd)                :  ping localhost 
argument    (sudo docker run -it ent_cmd google.com) :  ping google.com

.

To override EntryPoint argument, you need to supply entrypoint
sudo docker run -it --entrypoint="/bin/bash" ent_cmdd

ps: En presencia de EntryPoint, CMD mantendrá argumentos para alimentar a EntryPoint. En ausencia de EntryPoint, CMD será el comando que se ejecutará.

6

He leído todas las respuestas y quiero resumir para una mejor comprensión a primera vista como sigue:

En primer lugar, todo el comando que se ejecuta en el contenedor incluye dos partes: el comando y los argumentos.

  • ENTRYPOINT defines the executable invoked when the container is started (for command)

  • CMD specifies the arguments that get passed to the ENTRYPOINT (for arguments)

En el libro Kubernetes In Action se señala una nota importante al respecto. (Capítulo 7)

Although you can use the CMD instruction to specify the command you want to execute when the image is run, the correct way is to do it through the ENTRYPOINT instruction and to only specify the CMD if you want to define the default arguments.

También puede leer este artículo para obtener una gran explicación de una manera sencilla.

5

CMD:

  • CMD ["executable","param1","param2"]: ["executable","param1","param2"]es el primer proceso.
  • CMD command param1 param2: /bin/sh -c CMD command param1 param2es el primer proceso. CMD command param1 param2se bifurca desde el primer proceso.
  • CMD ["param1","param2"]: Este formulario se utiliza para proporcionar argumentos predeterminados para ENTRYPOINT.

ENTRYPOINT (La siguiente lista no considera el caso en el que CMD y ENTRYPOINT se usan juntos):

  • ENTRYPOINT ["executable", "param1", "param2"]: ["executable", "param1", "param2"]es el primer proceso.
  • ENTRYPOINT command param1 param2: /bin/sh -c command param1 param2es el primer proceso. command param1 param2se bifurca desde el primer proceso.

Como dijo Creack , CMD se desarrolló primero. Luego, ENTRYPOINT se desarrolló para una mayor personalización. Dado que no están diseñados en conjunto, existen algunas superposiciones de funciones entre CMD y ENTRYPOINT, que a menudo confunden a las personas.

3

CMDEl comando mencionado dentro del Dockerfilearchivo se puede anular a través del docker runcomando, mientras ENTRYPOINTque no.

1
  • 6
    docker run --helpcomando dice lo contrario:--entrypoint string Overwrite the default ENTRYPOINT of the imageiomv 1 de agosto de 2019 a las 16:06
2

La mayoría de la gente lo explica perfectamente aquí, así que no repetiré todas las respuestas. Pero para tener una buena sensación, sugeriría que lo pruebe usted mismo observando los procesos en el contenedor.

Cree un pequeño Dockerfile del formulario:

FROM ubuntu:latest
CMD /bin/bash

Constrúyalo, ejecútelo docker run -it theimagey ejecútelo ps -eo ppid,pid,argsen el contenedor. Compare esta salida con la salida que recibe de ps cuando usa:

  • docker run -it theimage bash
  • Reconstruyendo la imagen pero ENTRYPOINT /bin/bashejecutándola en ambos sentidos
  • Utilizando CMD ["/bin/bash"]
  • ...

De esta manera, verá fácilmente las diferencias entre todos los métodos posibles.

0
2

La documentación oficial de las mejores prácticas de Dockerfile hace un gran trabajo al explicar las diferencias. Mejores prácticas de Dockerfile

CMD:

La instrucción CMD debe usarse para ejecutar el software contenido en su imagen, junto con cualquier argumento. CMD casi siempre debe usarse en forma de CMD ["executable", "param1", "param2"…]. Por lo tanto, si la imagen es para un servicio, como Apache y Rails, ejecutaría algo como CMD ["apache2","-DFOREGROUND"]. De hecho, esta forma de instrucción se recomienda para cualquier imagen basada en servicios.

PUNTO DE ENTRADA:

El mejor uso para ENTRYPOINT es configurar el comando principal de la imagen, permitiendo que esa imagen se ejecute como si fuera ese comando (y luego usar CMD como los indicadores predeterminados).

1

• Un Dockerfile debe especificar al menos una instrucción CMD o ENTRYPOINT

• Solo se usará el último CMD y ENTRYPOINT en un Dockerfile

• ENTRYPOINT debe definirse cuando se usa el contenedor como ejecutable

• Debe utilizar la instrucción CMD como una forma de definir argumentos predeterminados para el comando definido como ENTRYPOINT o para ejecutar un comando ad-hoc en un contenedor.

• CMD se anulará cuando se ejecute el contenedor con argumentos alternativos

• ENTRYPOINT establece la aplicación concreta predeterminada que se utiliza cada vez que se crea un contenedor utilizando la imagen.

• Si acopla ENTRYPOINT con CMD, puede eliminar un ejecutable de CMD y dejar sus argumentos que se pasarán a ENTRYPOINT

• El mejor uso para ENTRYPOINT es establecer el comando principal de la imagen, permitiendo que esa imagen se ejecute como si fuera ese comando (y luego usar CMD como marcas predeterminadas)