RUN、CMD 和 ENTRYPOINT 这三个 Dockerfile 指令看上去很类似,很容易混淆。

简单的说:

RUN 执行命令并创建新的镜像层,RUN 经常用于安装软件包。

CMD 设置容器启动后默认执行的命令及其参数,但 CMD 能够被 docker run 后面跟的命令行参数替换。

ENTRYPOINT 配置容器启动时运行的命令。

Shell 和 Exec 格式

可以用两种方式指定 RUN、CMD 和 ENTRYPOINT 要运行的命令:Shell 格式和 Exec 格式,二者在使用上存在细微的区别。

Shell 格式

<instruction> <command>

例如:

RUN apt-get install python3  

CMD echo "Hello world"  

ENTRYPOINT echo "Hello world" 

当指令执行时,shell 格式底层会调用 /bin/sh -c <command>。

例如下面的 Dockerfile 片段:

 ENV name xxx
ENTRYPOINT echo "Hello, $name"

执行 docker run <image> 将输出:

Hello, xxx

注意环境变量 name 已经被值 xxx 替换。

Exec 格式

 <instruction> ["executable", "param1", "param2", ...]

例如:

 RUN ["apt-get", "install", "python3"]
CMD ["/bin/echo", "Hello world"]
ENTRYPOINT ["/bin/echo", "Hello world"]

当指令执行时,会直接调用 <command>,不会被 shell 解析。

以Dockerfile 片段为例:

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

运行容器将输出:

Hello, $name

注意环境变量“name”没有被替换。
如果希望使用环境变量,照如下修改

 ENV name xxx
ENTRYPOINT ["/bin/sh", "-c", "echo Hello, $name"]

运行容器将输出:

Hello, xxx

CMD 和 ENTRYPOINT 推荐使用 Exec 格式,指令可读性更强,更容易理解。RUN 则两种格式都可以。

RUN

  RUN 指令通常用于安装应用和软件包。

  RUN 在当前镜像的顶部执行命令,并通过创建新的镜像层。Dockerfile 中常常包含多个 RUN 指令。

  RUN 有两种格式:

  1. Shell 格式:RUN
  2. Exec 格式:RUN ["executable", "param1", "param2"]

可以使用 RUN 安装多个包:

RUN apt-get update && apt-get install -y \
bzr \
cvs \
git \
mercurial \
subversion

注意:apt-get update 和 apt-get install 被放在一个 RUN 指令中执行,这样能够保证每次安装的是最新的包。如果 apt-get install 在单独的 RUN 中执行,则会使用 apt-get update 创建的镜像层,而这一层可能是很久以前缓存的。

CMD

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

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

CMD 有三种格式:

  1. Exec 格式(推荐):CMD ["executable","param1","param2"]
  2. CMD ["param1","param2"] 为 ENTRYPOINT 提供额外的参数,此时 ENTRYPOINT 必须使用 Exec 格式。
  3. Shell 格式:CMD command param1 param2

举个栗子:

 root@ubuntu:~/# cat Dockerfile
FROM ubuntu
CMD echo "hello world"
root@ubuntu:~/#
root@ubuntu:~/# docker build -t cmd-eg-v1 .
Sending build context to Docker daemon .048kB
Step / : FROM ubuntu
---> 1d9c17228a9e
Step / : CMD echo "hello world"
---> Running in 73a418109975
Removing intermediate container 73a418109975
---> 44b793b3959c
Successfully built 44b793b3959c
Successfully tagged cmd-eg-v1:latest
root@ubuntu:~/#
root@ubuntu:~/# docker run -it cmd-eg-v1
hello world
root@ubuntu:~/# docker run -it cmd-eg-v1 /bin/bash
root@57afa1edf189:/#

在执行 docker run -it [image] /bin/bash,CMD 会被忽略掉,命令 bash 被执行。

ENTRYPOINT

ENTRYPOINT 指令可让容器以应用程序或者服务的形式运行。

ENTRYPOINT 看上去与 CMD 很像,它们都可以指定要执行的命令及其参数。区别在于 ENTRYPOINT 不会被忽略,一定会被执行,即使运行 docker run 时指定了其他命令。

ENTRYPOINT 有两种格式:

  1. Exec 格式(推荐):ENTRYPOINT ["executable", "param1", "param2"]
  2. Shell 格式:ENTRYPOINT command param1 param2

在为 ENTRYPOINT 选择格式时必须小心,因为这两种格式的效果差别很大。

Exec 格式

ENTRYPOINT 的 Exec 格式用于设置要执行的命令及其参数,同时可通过 CMD 提供额外的参数。

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

举个例子:

 root@ubuntu:~/# cat Dockerfile
FROM ubuntu
ENTRYPOINT ["/bin/echo", "Hello"]
CMD ["world"]
root@ubuntu:~/#
root@ubuntu:~/# docker build -t cmd-eg-v2 .
Sending build context to Docker daemon .048kB
Step / : FROM ubuntu
---> 1d9c17228a9e
Step / : ENTRYPOINT ["/bin/echo", "Hello"]
---> Running in fae6feb9277a
Removing intermediate container fae6feb9277a
---> 93c655c722d2
Step / : CMD ["world"]
---> Running in 0de0893f9c13
Removing intermediate container 0de0893f9c13
---> 3632ca1d41fa
Successfully built 3632ca1d41fa
Successfully tagged cmd-eg-v2:latest
root@ubuntu:~/#
root@ubuntu:~/# docker run -it cmd-eg-v2
Hello world
root@ubuntu:~/# docker run -it cmd-eg-v2 xxx
Hello xxx
root@ubuntu:~/#

Shell 格式

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

小结

  1. 使用 RUN 指令安装应用和软件包,构建镜像。
  2. 如果 Docker 镜像的用途是运行应用程序或服务,比如运行一个 MySQL,应该优先使用 Exec 格式的 ENTRYPOINT 指令。CMD 可为 ENTRYPOINT 提供额外的默认参数,同时可利用 docker run 命令行替换默认参数。
  3. 如果想为容器设置默认的启动命令,可使用 CMD 指令。用户可在 docker run 命令行中替换此默认命令。

---------------------------引用来自-----------------------------------

https://mp.weixin.qq.com/s?__biz=MzIwMTM5MjUwMg==&mid=2653587614&idx=1&sn=2070e193da6b71861052e393eccae055&chksm=8d308087ba4709915514e06e73bba8a93fca5510f910552a8290e9a1b4ae111d7a3fd230c0a5&scene=21#wechat_redirect

第 3 章 镜像 - 017 - RUN vs CMD vs ENTRYPOINT的更多相关文章

  1. RUN vs CMD vs ENTRYPOINT - 每天5分钟玩转 Docker 容器技术(17)

    RUN.CMD 和 ENTRYPOINT 这三个 Dockerfile 指令看上去很类似,很容易混淆.本节将通过实践详细讨论它们的区别. 简单的说: RUN 执行命令并创建新的镜像层,RUN 经常用于 ...

  2. RUN vs CMD vs ENTRYPOINT

    参考:https://www.ibm.com/developerworks/community/blogs/132cfa78-44b0-4376-85d0-d3096cd30d3f/entry/RUN ...

  3. 017、RUN、CMD、ENTRYPOINT (2019-01-08 周二)

    参考https://www.cnblogs.com/CloudMan6/p/6875834.html   RUN CMD ENTRYPOINT 这三个Dockerfile指令看上去很类似,很容易混淆. ...

  4. Dockerfile创建自定义Docker镜像以及CMD与ENTRYPOINT指令的比较

    1.概述 创建Docker镜像的方式有三种 docker commit命令:由容器生成镜像: Dockerfile文件+docker build命令: 从本地文件系统导入:OpenVZ的模板. 关于这 ...

  5. 15-RUN vs CMD vs ENTRYPOINT

    RUN.CMD 和 ENTRYPOINT 这三个 Dockerfile 指令看上去很类似,很容易混淆.本节将通过实践详细讨论它们的区别. 简单的说: RUN 执行命令并创建新的镜像层,RUN 经常用于 ...

  6. Dockerfile的 RUN和CMD

    在创建Dockerfile的时候,RUN和CMD都是很重要的命令.它们各自的作用分别如下: RUNRUN命令是创建Docker镜像(image)的步骤,RUN命令对Docker容器( containe ...

  7. Docker | dockerfile构建centos镜像,以及CMD和ENTRYPOINT的区别

    构建自己的centos镜像 docker pull centos下载下来的镜像都是基础版本,缺少很多常用的命令功能,比如:ll.vim等等, 下面介绍制作一个功能较全的自己的centos镜像. 步骤 ...

  8. 论docker中 CMD 与 ENTRYPOINT 的区别

    Dockerfile里有 CMD 与 ENTRYPOINT 两个功能咋看起来很相似的指令,开始的时候觉得两个互用没什么所谓,但其实并非如此: CMD指令: The main purpose of a ...

  9. 论docker中 CMD 与 ENTRYPOINT 的区别(转)

    Dockerfile 用于自动化构建一个docker镜像.Dockerfile里有 CMD 与 ENTRYPOINT 两个功能咋看起来很相似的指令,开始的时候觉得两个互用没什么所谓,但其实并非如此: ...

随机推荐

  1. oracle merge同时包含增、删、改

    原来一直没注意,merge是可以支持delete,只不过必须的是on条件满足,也就是要求系统支持逻辑删除,而非物理删除. Using the DELETE Clause with MERGE Stat ...

  2. uml类图和er图中主外键的表示区别

    在er图也就是数据库中,无论是mysql/oracle都是从表引用主表的pk作为外键. 而在uml类图表示法中,他们的顺序则刚好相反,从主对象导向到子对象,如下: 主体是资金借款方,征信信息和资金借款 ...

  3. Java 中断异常的正确处理方式

    处理InterruptedException 这个故事可能很熟悉:你正在写一个测试程序,你需要暂停某个线程一段时间,所以你调用 Thread.sleep().然后编译器或 IDE 就会抱怨说 Inte ...

  4. python简说(十三)递归

    #递归就是函数自己调用自己count = 0# def abc():# pass# abc()最多循环999次

  5. 牛客网数据库SQL实战(1-5)

    1.查找最晚入职员工的所有信息 CREATE TABLE `employees` ( `emp_no` int(11) NOT NULL, `birth_date` date NOT NULL, `f ...

  6. 盛世狂欢意犹未尽之恋舞OL折扣平台多角度体验

    2018国民级时尚音乐舞蹈手游<恋舞OL>,女生都爱玩的手机游戏.画风Q萌的3D音乐舞蹈手游,多人同时在线,玩法轻松休闲,浪漫场景自由社交互动,恋上指尖舞蹈. 小编看了上述介绍之后,感觉已 ...

  7. CentOS7学习记录(工具使用篇)

    一.   远程连接终端中文乱码:如xShell 检查当前系统语言:echo $LANG 查看系统安装语言包:locale ,如果包含zh_CN.UTF-8表示已经安装中文语言.如果没有中文包,使用命令 ...

  8. Restful framework【第八篇】频率组件

    基本使用 频率: -限制每个ip地址一分钟访问10次 -写一个类 from rest_framework.throttling import SimpleRateThrottle class Visi ...

  9. thinkphp在前端页面的js代码中可以使用 U方法吗? 可以使用模板变量如__URL__等吗?

    thinkphp在前端页面的js代码中可以使用 U方法吗? : 可以的! tp的U方法, 是"全局的", 什么是全局的? 就是, 可以在 "任何地方"使用的: ...

  10. UVA 10382 Watering Grass(区间覆盖,贪心)题解

    题意:有一块草坪,这块草坪长l 米,宽 w 米,草坪有一些喷头,每个喷头在横坐标为 p 处,每个喷头的纵坐标都是(w/2) ,并且喷头的洒水范围是一个以喷头为圆心,半径为 r 米的圆.每次最少需要打开 ...