dockerfile命令至ENTRYPOINT与CMD用法详解

首先明确一点

​ 不管是ENTRYPOINT指令还是CMD指令,虽然都是在Dockerfile中就已经定义完成了。但是在构建镜像的时候并不会被执行,只有在执行docker run命令启动容器时才会起作用。

同类覆盖原则

​ Dockerfile中只能有一个ENTRYPOINT命令,如果有很多个,那么最后一条会覆盖掉前面所有的ENTRYPOINT命令。

​ 同理,如果在启动的时候使用了 --entrypoint ,也将会覆盖Dockerfile中定义好的ENTRYPOINT命令。

​ 再同理,

​ Dockerfile中只能有一个CMD命令,如果有很多个,那么最后一条会覆盖掉前面所有的CMD命令。

​ 启动时候的CMD命令,例如run -d containerID /bin/bash 的CMD /bin/bash也会覆盖Dockerfile中定义好的CMD命令。

ENTRYPOINT优先原则

​ 执行docker run如果带有其他命令参数,如run -d $containerID /bin/bash ,那么将不会覆盖ENTRYPOINT指令,而是以参数的形式追加至ENTRYPOINT指令之后。

ENTRYPOINT

  • 用法一:用CMD来给ENTRYPOINT追加参数

​ 当我们再Dockerfile文件中定义了入下的ENTRYPOINT命令

ENTRYPOINT ["java","-jar", "demo.jar"]

​ 那么当我们运行此镜像执行docker run命令时,设置的任何命令参数或CMD指令的命令,都将作为ENTRYPOINT指令的命令参数,追加到ENTRYPOINT指令的命令之后。

如,在Dockerfile中有如上ENTRYPOINT指令的情况下,执行docker run $containerId &启动容器。则容器启动后执行的第一条完整命令如下:

java -jar demo.jar &
  • 用法二:屏蔽其他命令用法

可以发现,和上一种用法的区别在于少了中括号和引号,更加接近于我们执行bash命令的写法。

而事实上这种方法的本质也是通过在容器内部调用Shell来执行我们定义的ENTRYPOINT命令。也就是说下面的命令会被自动执行为:/bin/bash -c java -jar demo.jar

java -jar demo.jar

​ 而通过这种方式定义的ENTRYPOINT不接受任何参数,所有的命令行或CMD命令都会被屏蔽掉。

​ 这种方式,除了使用新的ENTRYPOINT命令,谁都无法影响其执行。

这样,ENTRYPOINT指令设置的top命令就不是容器中的第一个进程PID 1,这样在容器停止的时候就无法收到系统的SIGTERM信号。要想收到SIGTERM信号,务必使用Bash的内置exec命令使得top的PID 1,定义ENTRYPOINT指令如下:

ENTRYPOINT exec java -jar demo.jar

CMD

  • 用法一:作为ENTRYPOINT命令参数

格式:

CMD ["-p","-v"]

这种情况下,要求ENTRYPOINT命令和CMD命令同时存在,且都使用此种用法(中括号加双引号进行分隔),因为如果ENTRYPOINT使用的是上述bash的用法,CMD命令将不生效(无意义)。

CMD的命令会作为参数追加至ENTRYPOINT命令后。

  • 用法二:作为Shell脚本执行
 CMD echo "lingg"

同ENTRYPOINT命令的第二种用法一样,会先自动调用shell脚本,然后再shell脚本中执行CMD命令。

上述命令将被转化为:

 /bin/bash -c echo "lingg"
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值