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. 超详细 Nginx 极简教程,傻瓜一看也会!

    什么是Nginx? Nginx (engine x) 是一款轻量级的Web 服务器 .反向代理服务器及电子邮件(IMAP/POP3)代理服务器. 什么是反向代理? 反向代理(Reverse Proxy ...

  2. intel webrtc 部署

    org link conference server Configure the MCU server 1. set the maximum numbers of open files, runnin ...

  3. java常用类-StringBuffer,Integer,Character

    * StringBuffer: * 线程安全的可变字符串. * * StringBuffer和String的区别? * 前者长度和内容可变,后者不可变. * 如果使用前者做字符串的拼接,不会浪费太多的 ...

  4. Codeforces 866C Gotta Go Fast - 动态规划 - 概率与期望 - 二分答案

    You're trying to set the record on your favorite video game. The game consists of N levels, which mu ...

  5. 位运算之a^b

    题目链接:https://www.acwing.com/problem/content/91/ 参考链接:https://blog.csdn.net/chaiwenjun000/article/det ...

  6. SSM集成activiti6.0错误集锦(二)

    项目环境 Maven构建 数据库:Orcle12c 服务器:Tomcat9 <java.version>1.8</java.version> <activiti.vers ...

  7. 使用vs code搭建C开发环境

    关于搭建vscode的开发环境来开发c网上已经有很多类似的贴子,但是几乎都是直接给出tasks.json和launch.json文件,并未说明这两个文件的作用以及如何配置.这里面向纯小白着重说明下(1 ...

  8. BZOJ5018: [Snoi2017]英雄联盟

    Description 正在上大学的小皮球热爱英雄联盟这款游戏,而且打的很菜,被网友们戏称为「小学生」.现在,小皮球终于受不 了网友们的嘲讽,决定变强了,他变强的方法就是:买皮肤!小皮球只会玩N个英雄 ...

  9. 题解——洛谷P2294 [HNOI2005]狡猾的商人(差分约束)

    裸的差分约束 dfs判断负环,如果有负环就false,否则就是true 注意有多组数据,数组要清空 #include <cstdio> #include <algorithm> ...

  10. Docker save & load

    docker save Estimated reading time: 1 minute Description Save one or more images to a tar archive (s ...