Docker中的RUN vs CMD vs Entrypoint

命令RUN,CMD和Entrypoint通常会在Docker开发人员之间引起很多混乱。从概念上理解所有这三个命令将有助于更清楚地理解这三个命令。

当我们尝试使用dockerfile构建映像时,说明会逐步执行。第一条指令通常是提取基本映像,例如ubuntu,centos等OS发行版。此后,我们通过使用FROM和AS命令包含更多映像或修改映像来修改基本映像。每条这样的指令都会创建一个新的中间映像,并为每个映像创建缓存。最终的泊坞窗映像可以被视为分层结构,其中存在一个核心或基础映像,并且在其之上,还有多个分层的中间映像。

要深入了解所有这三个命令,我们首先需要了解什么是shell和exec形式。

可执行形式

该表格通常用于Entrypoint和CMD命令。它的形式是-

<instruction> [“executable”, “parameter”, “parameter”, ….]

当我们以这种形式执行指令时,不会进行外壳处理,并且直接调用可执行文件。

请请看以下命令。

RUN [“apt-get”, “install”, “vim”]
ENTRYPOINT [“/bin/echo”, “nhooo”]
CMD [“/bin/echo”, “nhooo”]

如果我们按照以下说明编写dockerfile,

ENV variable nhooo
ENTRYPOINT [“/bin/echo”, “$variable”]

当我们尝试运行该映像时,将生成以下输出。

$variable

外壳形式

当我们尝试使用shell形式执行指令时,会进行常规的shell处理。它在后台调用命令/ bin / sh -c {command}。

它的格式为-<您的指令> <命令>

请请看以下命令。

RUN apt-get -y update
CMD echo “nhooo”
ENTRYPOINT echo “nhooo”

以下dockerfile-

ENV variable nhooo
ENTRYPOINT echo “$variable”

将输出-

nhooo

现在我们已经深入理解了这两种形式,让我们继续这三个命令。

RUN命令始终在新层中执行。它允许您在现有图像层的顶部安装软件包和应用程序,并在其上面创建一个新层。

它可以用shell和exec两种形式编写。例子包括-

RUN apt-get -y update (shell form)
RUN [“apt-get”, “install”, “vim”] (exec form)

CMD

使用CMD命令,您将能够设置默认命令。如果运行特定容器而不指定某些命令,则将执行此操作。如果您在运行Docker容器时指定了一条命令,则默认命令将被忽略。请注意,如果您在dockerfile中指定了多个CMD指令,则仅执行最后一个。

以下是执行CMD命令的不同方法。

  • CMD <命令> parameter1,parameter2…。(外壳形式)

  • CMD [“可执行命令”,“ parameter1”,“ parameter2”,……。)(可执行格式)

  • CMD [“ parameter1”,“ parameter2”]

第三种方法用于设置一些其他默认参数,当您以可执行形式使用ENTRYPOINT时,并且如果您在命令行中未指定任何参数的情况下运行容器时,将在默认参数之后插入这些默认参数。

请看以下dockerfile中的命令。

CMD echo “nhooo”

如果运行时未指定参数(docker run -it image_name),则输出为-

nhooo

如果通过指定CLI参数(docker run -it image_name / bin / bash)运行它,它将仅打开bash。

入口点

它看起来类似于CMD命令。但是,不同之处在于,使用CLI参数运行容器时,它不会忽略参数。ENTRYPOINT命令的两种形式是-

  • ENTRYPOINT <命令> parameter1,parameter2,…(它是shell形式)

  • ENTRYPOINT [“可执行命令”,“ parameter1”,“ parameter2”,……。)(可执行格式)

当您使用ENTRYPOINT命令的可执行形式时,它将允许您使用CMD命令设置其他参数。如果以外壳形式使用它,它将忽略CMD参数或任何CLI参数。

考虑下面的示例。

ENTRYPOINT [“/bin/echo”, “nhooo”]
CMD [“Docker”]
  • 如果您尝试在不指定任何CLI参数的情况下运行容器(docker run -it image_name),则输出为-nhooo Docker

  • 如果指定CLI参数(docker run -it image_name DockerTutorials),则输出将为-nhooo DockerTutorials。

总之,如果要指定默认参数,并希望在指定CLI参数时将其覆盖,请使用CMD命令。并且,如果要在始终执行特定命令的条件下运行容器,请使用ENTRYPOINT。RUN仅用于在基础图像上构建其他图像层。