浅析 Dockerfile 构建缓存:原理与优化方法

本文详细解释了Docker镜像的分层结构,强调了UnionFS的作用以及构建镜像时如何利用缓存。介绍了构建缓存的工作原理,特别是ADD/COPY和RUN指令对缓存的影响,以及如何通过合并指令和正确安排顺序来最大化缓存效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Docker镜像的分层结构

  1. Docker镜像是由一层一层的文件系统组成,UnionFS将这些镜像层堆叠在一起
  2. 镜像层是只读的,构建完成后就不能更改了,即使在新的镜像层修改或删除了某些文件,也不会影响之前的镜像层内容
  3. 用Dockerfile构建镜像时,每个指令都会创建一个新的镜像层,镜像层会被缓存和复用

构建缓存的基本规则

构建镜像时,Docker 按照顺序逐步执行 Dockerfile 中的指令。对于每条指令,Docker 检查它是否可以重用构建缓存中的指令。

  1. 如果引用的父镜像在构建缓存中,下一个指令将会和所有从该基础镜像派生的子镜像做比较,如果和其中一个子镜像的指令相同,那么缓存命中,否则缓存失效
  2. 在大部分情况下,通过比较Dockerfile中的指令和子镜像已经足够了,但是有些指令需要进一步的检查
  3. 对于ADD和COPY指令,文件的内容会被检查,并且会计算每一个文件的校验码。在缓存查找期间,如果文件内容或元数据发生更改,那么缓存就会失效
  4. 除了ADD和COPY指令之外,缓存检查不会查看容器中的文件来判断是否命中缓存。例如,在处理RUN apt-get -y update指令时,不会检查容器中的更新文件来确定是否命中缓存,这种情况下只会检查指定字符串是否相同

一旦缓存失效,所有后续的 Dockerfile 指令都会生成新的镜像层,不再使用缓存。

如何充分利用缓存

  1. 将多个命令合并成单个RUN指令时,同时也要考虑将变更频率不同的命令分开
  2. 指令从变更不频繁到变更频繁的顺序来写
    a. 一般源代码会经常变化,所以要把安装依赖等不经常变动的步骤写在前面,拷贝源代码等经常变动的步骤写在后面
    b.如果是Python项目的话,先拷贝requerements.txt,然后进行pip install requerements.txt,最后再进行COPY代码
  3. ARG指令的变量值变化会导致缓存失效,所以最好在使用前定义,不要过早使用

参考

https://docs.docker.com/develop/develop-images/guidelines/#leverage-build-cache

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值