Dockerfile中RUN CMD以及ENTRYPOINT的区别
Dockerfile中的RUN,CMD,ENTRTPOINT三个指令均可以用来指明容器中所运行的指令,但这三者存在的细微的区别。
简单来说:
RUN
RUN指令一般用于在容器内安装软件包或者是执行其他的命令,如
RUN yum install -y telnet
RUN touch web.xml
CMD
CMD指令主要用来指明生成的Docker镜像在启动时的命令及参数,这个指令可以被docker run后面的命令所取代,比如下面这个Dockerfile文件
FROM busybox
CMD echo "hello world"
CMD指明了Docker镜像在运行时的输出一个"hello world"
[root@bochs Docker]# docker build -t test .
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM busybox
---> 83aa35aa1c79
Step 2/2 : CMD echo "hello world"
---> Running in a1a4d74137d2
Removing intermediate container a1a4d74137d2
---> 651b45b58fe9
Successfully built 651b45b58fe9
Successfully tagged test:latest
[root@bochs Docker]# docker run -it test
hello world
但是如果在docker run后添加其他指令。那么CMD将直接被替换
[root@bochs Docker]# docker run -it test ls
bin dev etc home proc root sys tmp usr var
ENTRYPOINT
ENTRYPOINT与CMD类似,区别在于ENTRYPOINT一定会被执行。如果一个Dockerfile中同时存在ENTRYPOINT和
CMD,CMD中的参数会被当做额外参数传给ENTRYPOINT。
[root@bochs Docker]# cat Dockerfile
FROM busybox
ENTRYPOINT ["/bin/echo","hello"]
CMD ["world"]
通过docker run 来运行,CMD变成了ENTRYPOINT的参数:
[root@bochs Docker]# docker run -it test2
hello world
但是如果指明docker run 的参数china,那么输出就会变为:
[root@bochs Docker]# docker run -it test2 china
hello china
原本CMD中带的参数world被docker run中的china所替换,但ENTRYPOINT自带的hello依然正常输出
Shell与Exec格式
CMD,RUN,ENTRYPOINT可以用两种格式来传递命令和参数,Shell一般表示为指令+命令,如:
RUN yum install -y telnet
CMD echo "hello world"
第一个大写的单词是Dockerfile的指令。后面跟的就是命令,可以拿到shell中单独执行
Exec格式可以表示为:指令+["命令","命令参数1","命令参数2",...],比如:
RUN ["yum","install","telnet"]
ENTRYPOINT ["/bin/bash","-c","echo hello world"]
对于这两种格式来说,CMD和ENTRYPOINT最好使用Exec格式,命令和参数分开,层次性较强,而RUN则都可以。
注意:ENTRYPOINT的Shell格式和Exec格式差异很大
比如下面这个Shell格式的ENTRYPOINT
FROM busybox
ENTRYPOINT echo "hello"
CMD "world"
在运行所生成的容器时,仅会输出hello,而CMD带的"world"会被忽略。同样的docker run带的参数也同样会被忽略
[root@bochs Docker]# docker run -it test
hello
[root@bochs Docker]# docker run -it test china
hello
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗