Dockerfile 中的 CMD 和 ENTRYPOINT 有什么区别?
我们可以通过在 Dockerfile 中指定指令来构建 Docker 镜像。Dockerfile 允许我们指定逐步指令,这些指令定义了创建容器环境的规则。Docker 容器是为要在其中运行的特定任务和进程而创建的。Dockerfile 中使用了三个重要的指令,这些指令允许我们定义需要在容器内运行哪些进程以及它们的顺序。
这三个指令是:
- RUN
- CMD
- ENTRYPOINT
RUN 指令很简单。我们可以使用 RUN 指令定义我们想要在容器内执行的简单子命令。例如,如果我们想要安装一个 pip 包,我们可以在 Dockerfile 中简单地使用“RUN pip install package_name”指令。
然而,另外两个指令——CMD 和 ENTRYPOINT,可能会让人感到困惑,特别是对于初学者而言。在本文中,我们将讨论这两个命令的用例和区别,以及一些有用的示例。但在我们深入了解它们之前,我们需要了解 Dockerfile 中编写指令的 shell 形式和 exec 形式。
Shell 形式
当我们使用 shell 形式指定指令时,正常的 shell 处理会在后台进行。守护进程在执行 shell 形式的命令时会在后台调用命令 shell。在 shell 形式中指定命令的格式是:
$ <instruction> <command>
可执行形式
当我们编写可执行形式的命令并执行这些命令时,正常的 shell 处理不会在后台发生。相反,可执行文件会直接被调用。在可执行形式中指定命令的格式是:
$ <instruction> ["executable", "parameter", "parameter", . . . .]
shell 形式的命令通常用于 RUN 指令,而可执行形式的命令通常用于 CMD 和 ENTRYPOINT 指令。
Explore our latest online courses and learn new skills at your own pace. Enroll and become a certified expert to boost your career.
CMD 指令
您可以使用 CMD 指令设置带有参数的默认命令。如果您运行 Docker 容器时没有指定任何额外的 CLI 命令,则将执行 CMD 指令。您可以将可执行文件包含为默认命令。但是,如果您选择省略它,则必须与 CMD 指令一起指定 ENTRYPOINT 指令。
如果您在 Docker run 命令中指定了参数,则使用 CMD 指令指定的默认参数将被忽略。此外,如果您在一个 Dockerfile 中指定了多个 CMD 指令,则只会执行最后指定的那个。
CMD 指令有三种形式:
- CMD ["only_executable","parameter_1","parameter_1"] (可执行形式)
- CMD ["parameter_1","parameter_2"] (用于为 ENTRYPOINT 指令提供默认参数)
- CMD command param1 param2 (shell 形式)
示例:
$ CMD echo "Command in Shell Form" $ CMD ["/bin/bash", "-c", "echo Command in Exec Form"]
ENTRYPOINT 指令
ENTRYPOINT 指令看起来与 CMD 指令几乎相同。但是,它们的主要区别在于,它不会忽略您在 Docker run 命令(CLI 参数)中指定的任何参数。
当我们以可执行形式指定 ENTRYPOINT 指令时,它允许我们使用 Dockerfile 中的 CMD 指令设置或定义一些附加参数。如果我们使用 shell 形式,它将忽略任何 CMD 参数甚至任何 CLI 参数。
ENTRYPOINT 指令的形式是:
- ENTRYPOINT ["only_executable", "parameter_1", "parameter_2"] (可执行形式)
- ENTRYPOINT command parameter_1 parameter_2 (shell 形式)
示例:
$ ENTRYPOINT echo "Welcome to TutorialsPoint" $ ENTRYPOINT ["/bin/bash", "-c", "echo Welcome to TutorialsPoint"]
最终想法!
总而言之,如果您想指定启动 Docker 容器时需要运行的带有参数的默认命令,可以使用 CMD 指令。如果您在 Docker run 命令中指定了参数,则使用 CMD 指令指定的参数将被忽略。这意味着使用 Docker run 命令的 CLI 参数将覆盖使用 CMD 指令指定的参数。
另一方面,ENTRYPOINT 指令有两种情况。如果您以 shell 形式使用 ENTRYPOINT 指令,并且您使用 CLI 参数甚至通过 CMD 命令提供其他参数,则 ENTRYPOINT 指令将覆盖所有这些参数。但是,如果您以可执行形式使用 ENTRYPOINT 指令,则可以使用 CMD 指令设置其他参数。
根据您的需求和用例,您可以采用其中任何一个命令。