一、CMD与ENTRYPOINT

  1. dockerfile中的 CMD

每个dockerfile中只能有一个CMD如果有多个那么只执行最后一个。

  • CMD启动docker的时候执行的命令,如果执行docker run命令时添加指令,会覆盖cmd的命令选项,举个简单例子:

docker run -itd —name test docker_image /bin/bash -c.
镜像名称后面跟了一个/bin/bash -c ,其实等价于在dockerfile中的CMD [“/bin/bash”,”-c”]
如果dockerfile中的CMD中有了CMD[“/bin/bash”,”-c”],那么就不用在执行的时候再添加了,如果添加了参数的话那么就相当于要执行你添加的参数,默认的CMD中的参数就无效了。

  1. dockerfile中的ENTRYPOINT

一个dockerfile中ENTRYPOINT也只能存在一个,若存在多个那么只执行最后一个
dockerfile中有ENTRYPOINT [“tail”,”-f”,”/usr/local/aaa”]这句,那么你启动的时候镜像就执行了这个里面的内容,如果你像上面带参数的话就相当于在这个执行的内容后面再加入参数
如果我们的dockerfile中有a中的这句话然后我们启动我们的docker:docker run -itd —name test docker_image /bin/bash -c.
此时就相当于我们启动docker的时候执行了:tail -f /usr/local/aaa /bin/bash -c

  1. CMD和ENTRYPOINT总结

一般还是会用entrypoint的中括号形式作为docker 容器启动以后的默认执行命令,里面放的是不变的部分,可变部分比如命令参数可以使用cmd的形式提供默认版本,也就是run里面没有任何参数时使用的默认参数。如果我们想用默认参数,就直接run,否则想用其他参数,就run 里面加参数。

二、COPY和ADD

  1. 唯一区别在于是否支持从远程URL获取资源。COPY指令只能从执行docker build所在的主机上读取资源并复制到镜像中。而ADD指令还支持通过URL从远程服务器读取资源并复制到镜像中。
  2. 满足同等功能的情况下,推荐使用COPY指令。ADD指令更擅长读取本地tar文件并解压缩。

    三、shell和exec格式

  3. Shell 格式

  • 例如:

RUN apt-get install python3
CMD echo “Hello world”
ENTRYPOINT echo “Hello world”

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

例如下面的 Dockerfile 片段:
ENV name xld
ENTRYPOINT echo “Hello, $name”

  • 执行 docker run 4.命令区别 - 图1 将输出:

Hello,xld
注意环境变量 name 已经被值 xld 替换。

  1. Exec 格式

[“executable”, “param1”, “param2”, …]

  • 例如:

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

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

例如下面的 Dockerfile 片段:
ENV name xld
ENTRYPOINT [“/bin/echo”, “Hello, $name”]

  • 运行容器将输出:

Hello, $name
注意环境变量“name”没有被替换。

  • 如果希望使用环境变量,照如下修改

ENV name xld
ENTRYPOINT [“/bin/sh”, “-c”, “echo Hello, $name”]
运行容器将输出:
Hello, xld

  1. 使用场景
  • CMD 和 ENTRYPOINT 推荐使用 Exec 格式,因为指令可读性更强,更容易理解。RUN 则两种格式都可以。
  • 使用 RUN 指令安装应用和软件包,构建镜像。
  • 如果 Docker 镜像的用途是运行应用程序或服务,比如运行一个 MySQL,应该优先使用 Exec 格式的 ENTRYPOINT 指令。CMD 可为 ENTRYPOINT 提供额外的默认参数,同时可利用 docker run 命令行替换默认参数。
  • 如果想为容器设置默认的启动命令,可使用 CMD 指令。用户可在 docker run 命令行中替换此默认命令。