Docker构建缓存

Docker镜像的分层结构

  1. Docker的镜像是由一层一层的文件系统组成,以UnionFS(联合文件系统)堆叠构成
  2. Dockerfile中的每个指令都会创建一个新的镜像层
  3. 镜像层将被缓存和复用
  4. 当Dockerfile的指令修改了,复制的文件变化了,或者构建镜像时指定的变量不同了,对应的镜像层缓存就会失效
  5. 某一层的镜像缓存失效之后,它之后的镜像层缓存都会失效
  6. 镜像层是不可变的,如果我们再某一层中添加一个文件,然后在下一层中删除它,则镜像中依然会包含该文件(只是这个文件在Docker容器中不可见了)

构建缓存的基本规则

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

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

如何充分利用缓存

从变更不频繁到变更频繁的顺序来写指令

  1. 一般源代码会经常变化,所以要把安装依赖等不太容易变动的步骤写在前面,拷贝源代码写在后面
  2. 如果是Python项目的话,先拷贝requerements.txt,然后进行pip install requerements.txt,最后再进行COPY代码

参考

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

你可能感兴趣的:(docker,缓存)