前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Docker RUN vs CMD vs ENTRYPOINT

Docker RUN vs CMD vs ENTRYPOINT

原创
作者头像
写bug的高哈哈
发布2024-11-07 09:49:35
730
发布2024-11-07 09:49:35

在 Dockerfile 中,RUN、CMD 和 ENTRYPOINT 这三条指令看起来相似,它们的作用都是在 Docker 镜像构建过程中运行指定的命令。有时候很容易造成混淆,接下来我们来详细探讨它们之间的区别。

RUN、CMD、ENTRYPOINT的作用

  • RUN:执行命令并创建新的镜像层。当你需要在镜像构建过程中安装软件包或应用程序时,就会用到 RUN。每执行一次 RUN 就会在镜像上添加一个新的层。
  • CMD:设置容器启动后默认执行的命令及其参数。不过,CMD 指定的命令可以通过 docker run 命令行参数来覆盖。它主要用于为容器设定默认启动行为。如果 Dockerfile 中有多个 CMD 指令,只有最后一个生效。
  • ENTRYPOINT:配置容器启动时运行的命令,功能上与 CMD 类似,但有一个关键区别——即使在 docker run 时指定了其他命令,ENTRYPOINT 也不会被忽略,而是会与这些命令结合使用(除非使用 --entrypoint 覆盖)。当容器作为应用程序或服务运行时,推荐使用 ENTRYPOINT,并且最好采用 Exec 格式。

我们可以通过两种方式指定 RUN、CMD 和 ENTRYPOINT 要运行的命令:Shell格式和Exec格式,这两种格式在使用上有一些微妙的差异。

Shell格式 和 Exec格式

Docker中的 RUN, CMD, 和 ENTRYPOINT 指令都可以采用两种不同的运行格式来指定要执行的命令:

Shell格式

Shell格式如下所示:

代码语言:shell
复制
<instruction> <command>

例如:

代码语言:Dockerfile
复制
RUN apt-get install python3
CMD echo "Hello world"
ENTRYPOINT echo "Hello world"

当执行命令时,Shell 格式的底层会使用 /bin/sh -c <command>。当你以Shell格式运行命令时,由 ENV 命令定义的环境变量可以被获取到。

代码语言:Dockerfile
复制
ENV name Cloud Man
ENTRYPOINT echo "Hello, $name"

输出:

代码语言:Dockerfile
复制
Hello, Cloud Man

Exec格式

Exec格式如下所示:

代码语言:Dockerfile
复制
<instruction> ["executable", "param1", "param2", ...]

例如:

代码语言:Dockerfile
复制
RUN ["apt-get", "install", "python3"]
CMD ["/bin/echo", "Hello world"]
ENTRYPOINT ["/bin/echo", "Hello world"]

当执行命令时,<command>将被直接调用,不会被shell解析。在 ENV 中定义的环境变量也没法获取到。

代码语言:Dockerfile
复制
ENV name Cloud Man

ENTRYPOINT ["/bin/echo", "Hello, $name"]

输出:

代码语言:Dockerfile
复制
Hello, $name

推荐使用Exec格式进行CMD和ENTRYPOINT的指定,因为这样指令更易于阅读和理解。

RUN

RUN命令通常用于安装应用程序和软件包。RUN 在当前镜像之上执行命令,并通过创建一个新的镜像层。Dockerfile 通常包含多个RUN指令。

CMD

CMD指令允许用户指定容器默认执行的命令。当容器启动并且没有为docker run指定其他命令时,此命令将运行。

  1. 如果docker run指定了另一个命令,CMD指定的默认命令将被忽略。
  2. 如果Dockerfile中有多个CMD指令,只有最后一个CMD有效。

CMD有三种格式:

  • Exec格式:CMD "executable","param1","param2"
  • CMD "param1", "param2",这种格式与ENTRYPOINT结合使用,以提供额外的参数
  • Shell格式:CMD command param1 param2

推荐使用Exec格式,因为它提供了更好的可读性。

ENTRYPOINT

The ENTRYPOINT directive allows the container to run as an application or service.

ENTRYPOINT在指定要执行的命令及其参数方面与CMD相似。不同之处在于,即使在运行docker run时指定了其他命令,ENTRYPOINT也不会被忽略,并且会被执行。

ENTRYPOINT有两种格式:

  • Exec格式:ENTRYPOINT "executable", "param1", "param2" 这是ENTRYPOINT推荐使用的格式。
  • Shell格式:ENTRYPOINT command param1 param2

ENTRYPOINT中的参数始终被使用,而CMD的额外参数可以在容器启动时动态替换。例如:

代码语言:Dockerfile
复制
ENTRYPOINT ["/bin/echo", "Hello"]

CMD ["world"]

# Output
Hello world

请注意,ENTRYPOINT的Shell格式会忽略CMD或docker run提供的任何参数。

代码语言:Dockerfile
复制
FROM busybox
ENTRYPOINT echo hello
CMD world


hello

Docker中的 --entrypoint 命令行选项允许你在运行容器时覆盖Docker镜像中指定的ENTRYPOINT指令。

代码语言:Dockerfile
复制
$ docker run --entrypoint="path/to/custom/entrypoint" imagename

默认情况下,当你运行一个Docker容器时,会执行镜像中ENTRYPOINT指令指定的命令。但是,如果你想覆盖这种行为,可以使用 --entrypoint 选项来指定一个不同的入口点来使用。有时这对容器内部环境问题的调试很有帮助。

总结

  1. 使用 RUN 命令来安装应用程序和包,并创建新的镜像层。
  2. 如果Docker镜像的目的是运行一个应用程序或服务,例如运行 MySQL,那么应该优先使用 Exec 格式的 ENTRYPOINT 命令。CMD 可以为 ENTRYPOINT 提供额外的默认参数,并且这些默认参数可以被 docker run 命令行替换。
  3. 如果你想为容器设置默认的启动命令,可以使用 CMD 命令。用户可以在 docker run 命令行中覆盖这个默认命令。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • RUN、CMD、ENTRYPOINT的作用
  • Shell格式 和 Exec格式
    • Shell格式
      • Exec格式
      • RUN
      • CMD
      • ENTRYPOINT
      • 总结
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档