环球滚动:Dockerfile之CMD、ENTRYPOINT指令
这里对Dockerfile中的CMD、ENTRYPOINT指令进行介绍
该指令可以用于指定容器被启动时需要运行的命令。具体地,其支持shell、exec两种形式的语法
#shell格式CMDcommandparam1param2#exec格式CMD["command","param1","param1"]
(资料图片仅供参考)
通常Docker中推荐使用exec格式语法,原因有二。一方面,shell格式语法下会通过/bin/sh -c来执行命令;另一方面,某些镜像甚至不包含Shell,致使shell格式下的命令无法被正常执行。但使用exec格式时,会无法获取环境变量的值。此时则可以考虑使用shell格式语法
shell格式下面通过Dockerfile定义一个名为demo1:test的镜像
#镜像demo1:testFROMbusybox:1.35.0#使用shell格式的CMDCMDpingbaidu.com
然后我们创建一个容器
dockerrun--namedemo1A--rm-itdemo1:test
如下所示,其会使用CMD指令设置的命令、参数执行
对于CMD指定的命令而言,不可以通过 docker run命令行实现传递参数。因为 CMD指令的命令、参数 会被 docker run命令行参数中指定的命令、参数 完全覆盖。例如我们创建一个容器,期望执行 ping weibo.com。则需要重新传递命令、参数
#错误方式:dockerrun--namedemo1B--rm-itdemo1:testweibo.com#正确方式dockerrun--namedemo1B--rm-itdemo1:testpingweibo.com
效果如下所示
又比如按下述方式创建命令,同理
dockerrun--namedemo1C--rm-itdemo1:testtop-H
效果如下所示
下面通过Dockerfile定义一个名为demo2:test的镜像
#镜像demo2:testFROMbusybox:1.35.0#使用exec格式的CMDCMD["ping","baidu.com"]
然后我们创建一个容器
dockerrun--namedemo2A--rm-itdemo2:test
如下所示,其会使用CMD指令设置的命令、参数执行
对于CMD指定的命令而言,不可以通过 docker run命令行实现传递参数。因为 CMD指令的命令、参数 会被 docker run命令行参数中指定的命令、参数 完全覆盖。例如我们创建一个容器,期望执行 ping weibo.com。则需要重新传递命令、参数
#错误方式dockerrun--namedemo2B--rm-itdemo2:testweibo.com#正确方式dockerrun--namedemo2B--rm-itdemo2:testpingweibo.com
效果如下所示
又比如按下述方式创建命令,同理
dockerrun--namedemo2C--rm-itdemo2:testtop-H
效果如下所示
该指令同样可以用于指定容器被启动时需要运行的命令。同理,其同样支持shell、exec两种形式的语法
#shell格式ENTRYPOINTcommandparam1param2#exec格式ENTRYPOINT["command","param1","param1"]
对于ENTRYPOINT指令而言,Docker中同样推荐使用exec格式语法,理由与CMD指令同理
shell格式下面通过Dockerfile定义一个名为demo3:test的镜像
#镜像demo3:testFROMbusybox:1.35.0#使用shell格式的ENTRYPOINTENTRYPOINTtop-b
然后我们创建一个容器
dockerrun--namedemo3A--rm-itdemo3:test
如下所示,其会使用ENTRYPOINT指令设置的命令、参数执行
ENTRYPOINT指令 所设置命令、参数可被 docker run命令行参数中指定要运行的命令 覆盖, 但需要使用 --entrypoint 选项进行显式覆盖。否则将会忽略命令行参数
#错误方式dockerrun--namedemo3B--rm-itdemo3:testifconfig#正确方式dockerrun--namedemo3C--rm-it--entrypointifconfigdemo3:test
效果如下所示
当我们使用 --entrypoint 选项进行显式覆盖命令时,还可以传递参数
dockerrun--namedemo3D--rm-it--entrypointpingdemo3:testbing.com.cn
效果如下所示
对于shell格式的ENTRYPOINT指令设置的命令而言,如果没有使用--entrypoint 选项。当通过 docker run命令行传递参数时, 其会被忽略
dockerrun--namedemo3E--rm-itdemo3:test-H-m
效果如下所示
下面通过Dockerfile定义一个名为demo4:test的镜像
#镜像demo4:testFROMbusybox:1.35.0#使用exec格式的ENTRYPOINTENTRYPOINT["top","-b"]
然后我们创建一个容器
dockerrun--namedemo4A--rm-itdemo4:test
如下所示,其会使用ENTRYPOINT指令设置的命令、参数执行
ENTRYPOINT指令 所设置命令、参数可被 docker run命令行参数中指定要运行的命令 覆盖, 但需要使用 --entrypoint 选项进行显式覆盖。否则将会忽略命令行参数
#错误方式dockerrun--namedemo4Bdemo4:testifconfig#正确方式dockerrun--namedemo4C--rm-it--entrypointifconfigdemo4:test
效果如下所示
当我们使用 --entrypoint 选项进行显式覆盖命令时,还可以传递参数
dockerrun--namedemo4D--rm-it--entrypointpingdemo4:testweibo.com
效果如下所示
对于exec格式的ENTRYPOINT指令设置的命令而言,如果没有使用--entrypoint 选项。当通过 docker run命令行实现传递参数时, 其会被追加
dockerrun--namedemo4E--rm-itdemo4:test-H-m
效果如下所示
对于大多数场景下,CMD、ENTRYPOINT指令都是互相通用的,而且一般也会只使用其中一种指令。具体地,CMD指令方便镜像使用者更改容器运行的命令,故适用于较为灵活的场景;而如果不期望镜像使用者去轻易更改容器运行的命令,故推荐使用ENTRYPOINT指令。同时如前文所述,exec格式较shell格式更为推荐。而对于CMD、ENTRYPOINT指令二者组合使用时,其效果可参考下图
事实上对于组合使用二者来说,更为常见的一种实践方式是通过exec格式的ENTRYPOINT设置固定的命令、参数,而利用exec格式的CMD 设置默认的可变参数
下面通过Dockerfile定义一个名为demo5:test的镜像
#镜像demo5:testFROMbusybox:1.35.0#使用exec格式的ENTRYPOINT设置固定的命令、参数ENTRYPOINT["top","-b"]#使用exec格式的CMD设置默认的可变参数CMD["-H"]
然后我们创建一个容器
dockerrun--namedemo5A--rm-itdemo5:test
效果如下所示
由于此场景下CMD指令提供的是一个默认的可变参数,故我们可以通过docker run命令行参数 来覆盖 CMD指定的默认可变参数
dockerrun--namedemo5B--rm-itdemo5:test-m
效果如下所示
同理,ENTRYPOINT指令 所设置命令、参数可被 docker run命令行参数中指定要运行的命令 覆盖, 使用 --entrypoint 选项进行显式覆盖即可。当然此时CMD指令设置的默认可变参数也将失效
dockerrun--namedemo5C--rm-it--entrypointifconfigdemo5:test
效果如下所示
当然使用 --entrypoint 选项进行显式覆盖命令时,依然可以传递参数
dockerrun--namedemo5D--rm-it--entrypointpingdemo5:testweibo.com
效果如下所示
相关阅读
-
世界热推荐:今晚7:00直播丨下一个突破...
今晚19:00,Cocos视频号直播马上点击【预约】啦↓↓↓在运营了三年... -
NFT周刊|Magic Eden宣布支持Polygon网...
Block-986在NFT这样的市场,每周都会有相当多项目起起伏伏。在过去... -
环球今亮点!头条观察 | DeFi的兴衰与...
在比特币得到机构关注之后,许多财务专家预测世界将因为加密货币的... -
重新审视合作,体育Crypto的可靠关系才能双赢
Block-987即使在体育Crypto领域,人们的目光仍然集中在FTX上。随着... -
简讯:前端单元测试,更进一步
前端测试@2022如果从2014年Jest的第一个版本发布开始计算,前端开发... -
焦点热讯:刘强东这波操作秀
近日,刘强东发布京东全员信,信中提到:自2023年1月1日起,逐步为...