【Docker】Dockerfile关键字参数 RUN、CMD、ENTRYPOINT

命令执行的时机,因为Dockerfile主要用来构建镜像,并非是立即生效运行的容器,所以在设计dockerfile时需要知道对应执行命令的时机:

DockerFile最佳实践

RUN

该RUN指令将在当前镜像顶部的新层中执行所有命令,并提交结果。生成的提交映像将用于中的下一步。RUN下一次构建期间,指令缓存不会自动失效。类似指令的缓存 RUN apt-get dist-upgrade -y将在下一次构建中重用。RUN指令的缓存可以通过使用–no-cache 标志来使无效,例如docker build --no-cache

docs.docker.com/engine/reference/builder/#run

格式

run的两种格式

  • RUN (shell form,命令在shell中运行,默认情况下/bin/sh -c在Linux 或 cmd /S /C 在Windows 上运行)
  • RUN ["executable", "param1", "param2"](exec form)

注意:要使用/ bin / sh以外的其他shell,请使用exec形式传入所需的shell。例如: RUN ["/bin/bash", "-c", "echo hello"]

CMD

CMD指令中只能有一条指令Dockerfile。如果您列出多个,CMD 则只有最后一个CMD才会生效。主要目的CMD是为执行中的容器提供默认值。这些默认值可以包含可执行文件,也可以省略可执行文件,在这种情况下,您还必须指定一条ENTRYPOINT 指令。

docs.docker.com/engine/reference/builder/#cmd

格式

cmd的三种格式

  • CMD ["executable","param1","param2"](exec形式,这是首选形式)
  • CMD ["param1","param2"](作为ENTRYPOINT的默认参数)
  • CMD command param1 param2(shell形式)

注意:如果CMD用于提供ENTRYPOINT 指令的默认参数,则CMD和ENTRYPOINT指令均应使用JSON数组格式指定。exec表单被解析为JSON数组,这意味着您必须在单词而非单引号(’)周围使用双引号(“)。请勿将RUN与CMD混淆。RUN实际上运行命令并提交结果;CMD在生成时不执行任何操作,但指定镜像的预期命令。

ENTRYPOINT

ENTRYPOINT允许您配置将作为可执行文件运行的容器。

docs.docker.com/engine/reference/builder/#entrypoint

格式

ENTRYPOINT两种方式

  • ENTRYPOINT ["executable", "param1", "param2"] (exec form,首选)
  • ENTRYPOINT command param1 param2(shell形式)

注意:Dockerfile只有中的最后一条ENTRYPOINT指令才会生效

最后

RUN:可多条,执行命令并创建新的Image Layer,可缓存用于下一步的RUN
CMD:只能有一条,设置容器启动后默认执行的命令和参数
ENTRYPOINT:设置容器启动时运行的命令,让容器以应用程序或者服务的形式运行,不会被忽略,一定会执行

一般会有以下两种书写格式:

Shell格式:

RUN apt-get install -y vim
CMD echo "hello docker"
ENTRYPOINT echo "hello docker"

Exec格式:

RUN ["apt-get","install","-y","vim"]
CMD ["/bin/echo","hello docker"]
ENTRYPOINT ["/bin/bash","-c","echo hello docker"]

了解CMD和ENTRYPOINT如何相互作用

CMDENTRYPOINT指令都定义了运行容器时要执行的命令。很少有规则描述他们的合作。

  1. Dockerfile应该指定CMD或ENTRYPOINT命令中的至少一个。

  2. 当使用容器作为可执行文件时,应该定义ENTRYPOINT。

  3. CMD应该被用作定义ENTRYPOINT命令或在容器中执行临时命令的默认参数的一种方式。

  4. 当使用替代参数运行容器时,将重写CMD。

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

No ENTRYPOINT ENTRYPOINT exec_entry p1_entry ENTRYPOINT [“exec_entry”, “p1_entry”]
No CMD error, not allowed /bin/sh -c exec_entry p1_entry exec_entry p1_entry
CMD [“exec_cmd”, “p1_cmd”] exec_cmd p1_cmd /bin/sh -c exec_entry p1_entry exec_entry p1_entry exec_cmd p1_cmd
CMD [“p1_cmd”, “p2_cmd”] p1_cmd p2_cmd /bin/sh -c exec_entry p1_entry exec_entry p1_entry p1_cmd p2_cmd
CMD exec_cmd p1_cmd /bin/sh -c exec_cmd p1_cmd /bin/sh -c exec_entry p1_entry exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd

你可能感兴趣的:(Docker)