解读三组容易混淆的Dockerfile指令
长话短说,今天分享三组容易混淆的Dockerfile指令, 帮助大家编写更优雅的Dockfile文件、构建更纯净的Docker镜像。
COPY vs ADD
COPY、ADD主体功能类似:从指定位置拷贝文件到Docker镜像。
COPY <src>... <dest> ADD <src>... <dest>
COPY 接收src、dest参数,只允许从Docker Engine主机上拷贝文件到Docker镜像;
ADD也能完成以上工作,但是ADD支持另外两种src:
- 文件源可以是URL
- 可以从src直接解压tar文件到目的地
ADD http://foo.com/bar.go /tmp/main.go # 从指定地址下载文件,添加到镜像文件系统的/tmp/main.go位置 ADD http://foo.com/bar.go /tmp/ # 因为以/结尾,将会引用url中的文件名添加到指定的目录下 ADD /foo.tar.gz /tmp/ # 自动解压主机文件到指定目录
有趣的是,URL下载和自动解压功能不能同时生效: 任何通过URL下载的压缩包文件不会自动解压。
- 如果拷贝本地文件到镜像,通常使用COPY,因为含义更明确
- ADD支持URL文件、自动解压到指定目录,这2个特性也很棒
ARG vs ENV
ARG、ENV也让人很疑惑的,都是Dockerfile中定义变量的指令。
ARG用于镜像构建阶段 build_time, 用于给构建提供外部变量, ENV用于将来运行的容器 runtime。
- 生成镜像后,ARG值不可用,正在运行的容器将无法访问ARG变量值。
ARG VAR_NAME 5 # 构建镜像时,可提供--build-arg VAR_NAME=6修改ARG值, ARG 和 docker build 时候的 --build-arg是搭配使用的。
- ENV主要是为容器环境变量提供默认值,正在运行的容器可访问环境变量(这是将配置传递给应用的好方法):
ENV VAR_NAME_2 6 # 启动容器时,可通过docker run -e "VAR_NAME_2=7"或docker-compose.yml提供新的环境变量值来覆盖Dockerfile中设置的ENV值。
一个小技巧: 构建镜像时不能使用命令行参数重写ENV,但是你可以使用ARG动态为ENV设置默认值:
# You can set VAR_A while building the image or leave it at the default ARG VAR_A 5 # VAR_B gets the (overridden) value of VAR_A ENV VAR_B $VAR_A
RUN vs ENTRYPOINT vs CMD
- RUN 在新层中执行命令并产生新镜像,主要用于安装新软件包。
- ENTRYPOINT 执行程序的启动命令,当您想将容器作为可执行文件运行时使用。
- CMD和ENTRYPOINT 都可以提供程序的启动命令;CMD另外一个作用是为执行中的容器提供默认值
- CMD ["executable","param1","param2"] (可执行形式,最常见)
- CMD command param1 param2 (脚本形式)
CMD echo "Hello world" # run -it <image> 输出 Hello world
但是当容器以命令启动,docker run -it
/bin/bash, CMD命令会被忽略,bash解析器将会运行:root@98e4bed87725:/#
- CMD ["param1","param2"] (作为ENTRYPOINT指令默认值,此时必须提供ENTRYPOINT指令,且ENTRYPOINT也必须以Json Array形式)
ENTRYPOINT ["/bin/echo", "Hello"] CMD ["world"] # run -it <image> 将会输出 Hello world; # run -it <image> earth 将会输出 Hello earth
当打算构建一个可执行的且常驻的镜像,最好选用ENTRYPOINT;
如果需要提供默认命令参数(可在容器运行时从命令行覆盖),请选择CMD
docker build 参数
https://docs.docker.com/reference/cli/docker/buildx/build/#build-arg
上面文档给出了 docker build提供的构建参数, 我这里记录几个重要的option:
- --build-arg: Set build-time variables
- --pull 作用是: 拉起基础镜像时强制拉取最新的版本
- --label: 给镜像打标签
- -t name and tag
Reference
本文来自博客园,作者:{有态度的马甲},转载请注明原文链接:https://www.cnblogs.com/JulianHuang/p/13060375.html
欢迎关注我的原创技术、职场公众号, 加好友谈天说地,一起进化
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?