Dockerfile中CMD和ENTRYPOINT有什么区别?

Gol*_*den 1484 docker

在Dockerfiles中有两个看起来与我类似的命令:CMDENTRYPOINT.但是我猜它们之间存在着一种(微妙的?)差异 - 否则对于同样的事情来说两个命令就没有任何意义.

文档说明了 CMD

CMD的主要目的是为执行容器提供默认值.

并为ENTRYPOINT:

ENTRYPOINT可帮助您配置可作为可执行文件运行的容器.

那么,这两个命令之间的区别是什么?

cre*_*ack 1561

Docker有一个默认入口点,/bin/sh -c但它没有默认命令.

当您像这样运行docker时: docker run -i -t ubuntu bash 入口点是默认值/bin/sh -c,图像是ubuntu,命令是bash.

该命令通过入口点运行.即,实际执行的事情是/bin/sh -c bash.这使得Docker可以RUN依靠shell的解析器快速实现.

后来,人们要求能够自定义这个,所以ENTRYPOINT并且--entrypoint被介绍了.

ubuntu上面示例中的所有内容都是命令,并传递给入口点.使用该CMD指令时,就像您正在做的那样docker run -i -t ubuntu <cmd>.<cmd>将是入口点的参数.

如果您改为输入此命令,也会得到相同的结果docker run -i -t ubuntu.你仍然会在容器中启动一个bash shell,因为ubuntu Dockerfile指定了一个默认的CMD:CMD ["bash"]

当所有内容都传递到入口点时,您可以从图像中获得非常好的行为.@Jiri示例很好,它显示了如何将图像用作"二进制".当["/bin/cat"]用作入口点然后做docker run img /etc/passwd,你得到它,/etc/passwd是命令并传递给入口点,因此最终结果执行就是这样/bin/cat /etc/passwd.

另一个例子是将任何cli作为入口点.例如,如果你有一个redis图像,而不是运行docker run redisimg redis -H something -u toto get key,你可以简单地运行,ENTRYPOINT ["redis", "-H", "something", "-u", "toto"]然后像这样运行相同的结果:docker run redisimg get key.

  • 这是一个很棒的答案.我认为Docker文档应该在一个名为`CMD` vs`ENTRYPOINT`的部分中添加它. (75认同)
  • 多亏了这一点,历史背景有很多帮助,因为我正在努力记住关于被覆盖的内容和附加内容的看似神秘的规则等.技术文档编写者无处不在的有用点:帮助读者构建系统的心理模型,不要只列出事实和情景:-) (12认同)
  • 默认情况下没有"ENTRYPOINT"; 是否使用shell取决于`CMD`命令的使用形式(https://docs.docker.com/engine/reference/builder/#cmd). (7认同)
  • @Webman No.他们是两个不同的指示.如果它们都存在,CMD将被视为ENTRYPOINT的参数. (5认同)
  • 注意:当前接受的答案似乎不是最新的:例如,*Docker 有一个默认入口点“/bin/sh -c”* 的第一个评论不准确(至少不再准确),并且它未参考官方文档;所以您可能想看看[其他答案](/sf/answers/2758614421/)? (4认同)
  • 一点也不.ENTRYPOINT设置一个可以(但可以在运行时覆盖)的元数据,所以如果你没有改变任何东西,在启动容器后,结果将是相同的,但是,RUN将在构建时被执行,无论你是什么在运行时,它会在这里. (3认同)
  • 请问 ENTRYPOINT 会覆盖 CMD 吗? (2认同)
  • 我刚刚在评论中偶然发现了一些东西。有一个特殊的软件可以充当“ENTRYPOINT”:https://github.com/Yelp/dumb-init (2认同)

Dai*_*shi 530

ENTRYPOINT规定将始终容器启动时执行的命令.

CMD指定参数,将被输送到ENTRYPOINT.

如果您想制作专用于您将使用的特定命令的图像 ENTRYPOINT ["/path/dedicated_command"]

否则,如果您想为一般目的制作图像,您可以保留ENTRYPOINT未指定并使用,CMD ["/path/dedicated_command"]因为您可以通过提供参数来覆盖设置docker run.

例如,如果您的Dockerfile是:

FROM debian:wheezy
ENTRYPOINT ["/bin/ping"]
CMD ["localhost"]
Run Code Online (Sandbox Code Playgroud)

不带任何参数运行映像将ping 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
Run Code Online (Sandbox Code Playgroud)

现在,使用参数运行图像将ping参数:

$ 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
Run Code Online (Sandbox Code Playgroud)

为了比较,如果您的Dockerfile是:

FROM debian:wheezy
CMD ["/bin/ping", "localhost"]
Run Code Online (Sandbox Code Playgroud)

不带任何参数运行映像将ping 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
Run Code Online (Sandbox Code Playgroud)

但是使用参数运行图像将运行参数:

docker run -it test bash
root@e8bb7249b843:/#
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参阅Brian DeHamer的这篇文章:https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd/

  • `ENTRYPOINT指定一个在容器启动时始终执行的命令.CMD指定将被提供给ENTRYPOINT的参数是一个很好的相关摘要. (178认同)
  • `ENTRYPOINT` 通常指向一个条目**脚本**(而不是命令),它可以执行许多有用的操作,例如:在执行之前验证需求(例如对依赖项的就绪性探测);proxy/wrap 命令来验证它,或者更改执行用户,或者更改文件的所有者(例如,在 Minikube 上安装 `hostPath` 时,默认情况下文件会被 *UID/GID* `1000:1000` 覆盖) , ETC.. (5认同)
  • ENTRYPOINT 也可以使用 --entrypoint 标志覆盖。例如 docker run -it --entrypoint bash test (4认同)
  • 我喜欢你的例子,它真的很有帮助! (4认同)
  • 这应该是所选择的答案,因为它立即切中要点并避免模棱两可(且措辞糟糕)的语言。 (3认同)
  • @Jingguo Yao:如果 CMD 包含诸如 - CMD ["nginx","-g","daemon","off"] 这样的命令怎么办?会被拴起来吗? (2认同)

Raf*_*sin 200

docker docs说,

CMD和ENTRYPOINT指令都定义了在运行容器时执行的命令.很少有规则描述他们的合作.

  1. Dockerfile应至少指定一个CMD或多个ENTRYPOINT命令.
  2. ENTRYPOINT 应该在将容器用作可执行文件时定义.
  3. CMD应该用作定义ENTRYPOINT命令的默认参数或在容器中执行ad-hoc命令的方法.
  4. CMD 在使用备用参数运行容器时将覆盖.

下表显示了针对不同ENTRYPOINT/ CMD组合执行的命令:

- 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  ?
????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

- 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   ?
?????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

- 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  ?
????????????????????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

  • 这是一个如此简单和重点的答案. (7认同)
  • `ENTRYPOINT exec_entry p1_ent` 的解释是错误的。shell 形式防止使用任何 CMD 或运行命令行参数 - https://docs.docker.com/engine/reference/builder/#entrypoint (3认同)
  • 努力发现每个表中的两个中间行是否需要重复。仅仅是虚拟命令不同还是我错过了由中间行复制引入的一些_实际_信息? (3认同)
  • @Danielo515“px_cmd”和“exec_entry”都只是这里的虚拟字符串。您可能会注意到“/bin/sh -c”会被添加到 CMD 作为前缀,而 CMD 是用可执行语法(而不是列表语法)编写的。 (2认同)
  • @MariuszMiesiak 现在已更新。感谢您的反馈意见。 (2认同)
  • 顺便说一句:这个答案绝对应该是公认的答案!(而[当前的](/sf/answers/1509549331/)声称“Docker有一个默认入口点,即`/bin/sh -c`”…) (2认同)

Jir*_*iri 163

是的,这是个好问题.我还不完全理解它,但是:

我知道这ENTRYPOINT是正在执行的二进制文件.您可以通过--entrypoint =""覆盖入口点.

docker run -t -i --entrypoint="/bin/bash" ubuntu
Run Code Online (Sandbox Code Playgroud)

CMD是容器的默认参数.如果没有入口点,则default参数是执行的命令.使用入口点,cmd作为参数传递给入口点.您可以使用入口点模拟命令.

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

# with entry point, emulating cat command
docker run --entrypoint="/bin/cat" ubuntu /etc/passwd
Run Code Online (Sandbox Code Playgroud)

因此,主要优点是使用入口点可以将参数(cmd)传递给容器.要实现此目的,您需要同时使用:

# Dockerfile
FROM ubuntu
ENTRYPOINT ["/bin/cat"]
Run Code Online (Sandbox Code Playgroud)

docker build -t=cat .
Run Code Online (Sandbox Code Playgroud)

然后你可以使用:

docker run cat /etc/passwd
#              ^^^^^^^^^^^
#                   CMD
#          ^^^      
#          image (tag)- using the default ENTRYPOINT
Run Code Online (Sandbox Code Playgroud)


Tom*_*vid 42

直觉 CMD和ENTRYPOINT之间的区别:

  • ENTRYPOINT:容器启动时运行的命令.
  • CMD:在容器启动时运行的命令或ENTRYPOINT的参数(如果已指定).

是的,它正在混淆.

运行docker run时,您可以覆盖其中的任何一个.

CMD和ENTRYPOINT之间的区别:

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
Run Code Online (Sandbox Code Playgroud)

更多关于CMD和之间的区别ENTRYPOINT:

参数docker run例如/ bin/bash的覆盖我们Dockerfile写任何CMD命令.

使用常规命令(例如)时,无法在运行时覆盖ENTRYPOINT docker run [args].所述args在端部docker run [args]被设置为参数入口点.通过这种方式,我们可以创建一个container像普通二进制文件一样的东西ls.

所以CMD可以作为ENTRYPOINT的默认参数,然后我们可以从[args]覆盖CMD args.

ENTRYPOINT可以覆盖--entrypoint.


upi*_*tau 36

简而言之:

  • CMD设置默认命令和/或参数,当docker容器运行时,可以从命令行覆盖这些命令和/或参数.
  • ENTRYPOINT命令和参数不会从命令行覆盖.相反,所有命令行参数将在ENTRYPOINT参数之后添加.

如果您需要更多详细信息或想在示例中看到差异,可以通过大量示例全面比较CMD和ENTRYPOINT的博客文章 - http://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/

  • 可以使用“--entrypoint”从命令行覆盖入口点 (2认同)

zan*_*ngw 28

有一些很好的答案。我想通过每个文档的演示来解释它

  • CMD 定义容器的默认命令和/或参数。如果您需要用户可以轻松覆盖的默认命令,则 CMD 是最好使用的指令。如果一个 Dockerfile 有多个 CMD,它只会应用最后一个的指令。
  • ENTRYPOINT 当您想定义具有特定可执行文件的容器时,首选。

ENTRYPOINT 除非添加--entrypoint 标志,否则在启动容器时 不能覆盖 an 。

  1. CMD

Docker 文件

  FROM centos:8.1.1911

  CMD ["echo", "Hello Docker"]
Run Code Online (Sandbox Code Playgroud)

运行结果

$ sudo docker run <image-id>
Hello Docker
$ sudo docker run <image-id> hostname   # hostname is exec to override CMD
244be5006f32
Run Code Online (Sandbox Code Playgroud)
  1. 入口点

Docker 文件

  FROM centos:8.1.1911

  ENTRYPOINT ["echo", "Hello Docker"]
Run Code Online (Sandbox Code Playgroud)

运行结果

$ sudo docker run <image-id>
Hello Docker
$ sudo docker run <image-id> hostname   # hostname as parameter to exec
Hello Docker hostname
Run Code Online (Sandbox Code Playgroud)
  1. 在许多情况下,结合 CMD 和 ENTRYPOINT 将是您的 Docker 容器的最佳解决方案。在这种情况下, 可执行文件用 ENTRYPOINT 定义,而 CMD 指定默认参数。

Docker 文件

  FROM centos:8.1.1911

  ENTRYPOINT ["echo", "Hello"]
  CMD ["Docker"]
Run Code Online (Sandbox Code Playgroud)

运行结果

$ sudo docker run <image-id>
Hello Docker
$ sudo docker run <image-id> Ben
Hello Ben
Run Code Online (Sandbox Code Playgroud)


Xia*_*com 15

接受的答案很棒,可以解释历史.我发现这个表格从官方文档"CMD和ENTRYPOINT如何互动"中解释得非常好: 在此输入图像描述


Mah*_*rus 15

我想轻松区分CMD、RUN 和 ENTRYPOINT之间的差异。

\n

让\xe2\x80\x99s 以节点的 npm init 为例。

\n

命令:

\n

让\xe2\x80\x99s 假设下面是我们在 dockerfile 中添加的初始命令

\n
CMD [ "npm", "init" ]\n
Run Code Online (Sandbox Code Playgroud)\n

现在,如果我跑docker run -t node npm install

\n

它将覆盖 dockerfile 中的 npm init 命令。

\n
CMD [ "npm", "init" ] This will become  CMD [ "npm", "install" ]\n
Run Code Online (Sandbox Code Playgroud)\n

它将执行该npm install命令,而不是npm init用 npm install 覆盖该命令。

\n

现在,让\xe2\x80\x99s 谈谈

\n

入口点 :

\n

让\xe2\x80\x99s 假设在 docker 文件中添加相同的命令,但使用 ENTRYPOINT

\n
ENTRYPOINT [ "npm", "init" ]\n
Run Code Online (Sandbox Code Playgroud)\n

现在,如果我跑docker run -t node install

\n

它将在 dockerfile 中附加 npm init 命令和 npm install。

\n
ENTRYPOINT [ "npm", "init" ] This will become  ENTRYPOINT [ "npm", "init", "install" ]\n
Run Code Online (Sandbox Code Playgroud)\n

它将执行 npm init 和 npm install 命令。

\n

总结 :

\n

RUN:这将在生成图像时执行。用于安装任何依赖项,例如node_modules。前任。RUN npm install

\n

CMD :当您想要覆盖完整命令时使用

\n

ENTRYPOINT:当您想要附加一些附加命令时使用。

\n


rka*_*ach 13

我遇到了这个问题,一开始我发现说实话真的很混乱,我认为这种混乱来自使用“CMD”这个词,因为实际上那里的内容充当了论点。所以在挖掘了一点之后,我明白了它是如何工作的。基本上:

ENTRYPOINT --> 您在此处指定的是容器启动时要执行的命令。如果您省略此定义,docker 将用于/bin/sh -c bash运行您的容器。

CMD --> 这些是附加到 ENTRYPOINT的参数,除非用户指定一些自定义参数,即:docker run ubuntu <custom_cmd>在这种情况下,docker 将运行而不是附加在 CMD 部分中的图像上指定的内容ENTRYPOINT <custom_cmd>。如果未指定 ENTRYPOINT,这里的内容将被传递给/bin/sh -c实际上作为启动容器时要执行的命令。

作为一切,最好通过示例来解释正在发生的事情。因此,假设我使用以下规范Dockerfile创建了一个简单的docker 镜像

From ubuntu
ENTRYPOINT ["sleep"]
Run Code Online (Sandbox Code Playgroud)

然后我通过运行以下命令来构建它:

docker build . -t testimg
Run Code Online (Sandbox Code Playgroud)

这将创建一个每次运行时都会休眠的容器。所以如果我按如下方式运行它:

docker run testimg
Run Code Online (Sandbox Code Playgroud)

我会得到以下信息:

sleep: missing operand
Try 'sleep --help' for more information.
Run Code Online (Sandbox Code Playgroud)

发生这种情况是因为入口点是需要参数的“sleep”命令。所以为了解决这个问题,我只提供睡眠的数量:

docker run testimg 5
Run Code Online (Sandbox Code Playgroud)

这将正确运行,因此容器将运行,休眠 5 秒并退出。正如我们在这个例子中看到的,docker 只是将图像名称后面的内容附加到入口点 binary docker run testimg <my_cmd>。如果我们想将默认值(默认参数)传递给入口点会发生什么?在这种情况下,我们只需要在CMD部分指定它,例如:

From ubuntu
ENTRYPOINT ["sleep"]
CMD ["10"]
Run Code Online (Sandbox Code Playgroud)

在这种情况下,如果用户不传递任何参数,容器将使用默认值 (10) 并将其传递给入口点 sleep。

现在让我们只使用 CMD 并省略 ENTRYPOINT 定义:

FROM ubuntu
CMD ["sleep", "5"]
Run Code Online (Sandbox Code Playgroud)

如果我们重建并运行这个镜像,它基本上会休眠 5 秒。

总而言之,您可以使用ENTRYPOINT使您的容器充当可执行文件。您可以使用CMD为入口点提供默认参数,或者在启动容器时运行自定义命令,该命令可由用户从外部覆盖。


Mar*_*oun 12

我将以示例1的方​​式添加答案,这可能有助于您更好地理解差异。

假设我们要创建一个在启动时始终运行sleep命令的映像。我们将创建自己的图像并指定一个新命令:

FROM ubuntu
CMD sleep 10
Run Code Online (Sandbox Code Playgroud)

现在,我们构建图像:

docker build -t custom_sleep .
docker run custom_sleep
# sleeps for 10 seconds and exits
Run Code Online (Sandbox Code Playgroud)

如果要更改秒数怎么办?我们将不得不更改Dockerfile值,因为该值在此处进行了硬编码,或者通过提供不同的值来覆盖该命令:

docker run custom_sleep sleep 20
Run Code Online (Sandbox Code Playgroud)

尽管这可行,但这不是一个好的解决方案,因为我们有一个多余的“ sleep”命令(容器的目的是sleep,因此必须显式指定该sleep命令不是一个好习惯)。

现在让我们尝试使用以下ENTRYPOINT指令:

docker build -t custom_sleep .
docker run custom_sleep
# sleeps for 10 seconds and exits
Run Code Online (Sandbox Code Playgroud)

该指令指定在容器启动时将运行的程序

现在我们可以运行:

docker run custom_sleep sleep 20
Run Code Online (Sandbox Code Playgroud)

那么默认值呢?好吧,你猜对了:

FROM ubuntu
ENTRYPOINT sleep
Run Code Online (Sandbox Code Playgroud)

ENTRYPOINT是将要运行的程序,并通过在容器上的值将被附加到它。

ENTRYPOINT可通过指定覆盖--entrypoint标志,后面是要使用新的切入点。

不是我的,我曾经看过提供此示例的教程

  • 以下是教程的链接:https://youtu.be/OYbEWUbmk90。它可能对未来的用户有用。 (3认同)
  • 我认为这个答案是最好的。对于我这个 Docker 菜鸟来说,这比其他答案要清楚得多。 (3认同)
  • 我在网上找到的最好的解释。多谢! (3认同)
  • 谢谢你!对于我(docker 初学者)来说,这个示例的解释比公认的答案要清楚得多。 (2认同)

小智 6

代码中的 EntryPoint函数的评论

// ENTRYPOINT/usr/sbin/nginx.

//将入口点(默认为sh -c)设置为/ usr/sbin/nginx.

//将接受CMD作为/ usr/sbin/nginx的参数.

文件的另一个参考

您可以使用ENTRYPOINT的exec形式设置相当稳定的默认命令和参数,然后使用CMD设置更可能更改的其他默认值.

例:

FROM ubuntu:14.04.3
ENTRYPOINT ["/bin/ping"]
CMD ["localhost", "-c", "2"]
Run Code Online (Sandbox Code Playgroud)

构建:sudo docker build -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
Run Code Online (Sandbox Code Playgroud)

.

To override EntryPoint argument, you need to supply entrypoint
sudo docker run -it --entrypoint="/bin/bash" ent_cmdd
Run Code Online (Sandbox Code Playgroud)

ps:在EntryPoint存在的情况下,CMD将保留参与EntryPoint的参数.在没有EntryPoint的情况下,CMD将成为将要运行的命令.


fgu*_*gul 6

我已经阅读了所有答案,我想总结一下,以便乍一看更好地理解,如下所示:

首先,在容器中执行的整个命令包括两部分: 命令参数

  • ENTRYPOINT定义容器启动时调用的可执行文件(用于命令)

  • CMD指定传递给 ENTRYPOINT 的参数(用于参数)

Kubernetes In Action一书中指出了一个关于它的重要说明。(第7章)

虽然可以使用CMD指令指定镜像运行时要执行的命令,但正确的方法是通过ENTRYPOINT指令进行,并且只有在要定义默认参数时才指定CMD

您也可以阅读这篇文章以简单的方式进行很好的解释


Jin*_*Yao 5

指令:

  • CMD ["executable","param1","param2"]:["executable","param1","param2"]是第一个过程。
  • CMD command param1 param2:/bin/sh -c CMD command param1 param2是第一个过程。CMD command param1 param2从第一个进程分叉。
  • CMD ["param1","param2"]: 此表单用于为 提供默认参数ENTRYPOINT

ENTRYPOINT(以下列表不考虑CMD和ENTRYPOINT一起使用的情况):

  • ENTRYPOINT ["executable", "param1", "param2"]:["executable", "param1", "param2"]是第一个过程。
  • ENTRYPOINT command param1 param2:/bin/sh -c command param1 param2是第一个过程。command param1 param2从第一个进程分叉。

正如creak所说,CMD 是最先开发的。然后开发了 ENTRYPOINT 以进行更多定制。由于它们不是一起设计的,因此 CMD 和 ENTRYPOINT 之间存在一些功能重叠,这经常使人们感到困惑。