跳到主要内容

合理使用缓存

2024年06月24日
柏拉文
越努力,越幸运

一、认识


Docker构建缓存机制是为了提高镜像构建的效率。它会缓存每个构建步骤的结果,并在后续构建中复用这些结果,从而避免重复执行相同的指令。

合理利用 Docker 的缓存机制可以显著提升镜像构建的效率。在编写 Dockerfile 时,应该尽量将变动频率高的指令放在后面,并利用分阶段构建来管理缓存。同时,在需要时可以使用 --no-cache 强制构建不使用缓存,并定期清理未使用的资源来保持系统的整洁。

1.1 原理

  1. 分层缓存:每个 Dockerfile 指令(如 FROM, COPY, RUN, CMD 等)都会创建一个新的镜像层。Docker 会缓存每一层的结果。

  2. 层的哈希值Docker 使用每一层的内容(包括指令和指令的上下文,例如文件内容、文件权限等)的哈希值来判断缓存是否可用。

  3. 缓存命中:如果 Docker 在构建过程中检测到某个指令的哈希值与之前构建的哈希值相同,则会使用缓存的结果,而不重新执行该指令。

  4. 缓存失效: 缓存的失效是逐层的,一旦某一层的缓存失效,后续所有层的缓存也都会失效。这意味着 Dockerfile 的指令顺序非常重要。比如说:通过 COPY . /server 复制整个项目目录,只要项目中有任何文件发生变化,这一层及之后的层都会重新构建。RUN npm installCOPY . /server 之后, 如果上一步缓存失效,这一步也会重新执行,否则使用缓存。

1.2 优化

  1. 将变动频率高的指令放在后面:例如,将 COPY . /server 放在 RUN npm install 之后,因为项目代码更频繁地变化,而依赖项相对稳定。

  2. 分阶段构建:利用多阶段构建,将不同阶段的缓存分开管理,以减少缓存失效的影响。

二、操作


2.1 COPY . .

COPY . . 对于构建上下文目录到容器的操作,只要构建上下文目录中的任何文件发生变化, COPY . . 这一层及其之后的层都会重新构建。所以 COPY . . 尽可能的往后放。

2.1 RUN npm install

RUN npm install 操作尽可能放到其他指令的前面,因为 项目依赖 一般而言是比较稳定的。

三、最佳实践


2.1 Web 构建

2.2 Node 构建

Dockerfile

FROM node:latest
WORKDIR /server
COPY package*.json /server
RUN npm install
COPY . /server
EXPOSE 4000
CMD ["node","index.js"]

.dockerignore

node_modules
dist

构建 Docker 镜像

docker build --no-cache -t node-build .

使用 Docker 镜像

docker run -d --name node-build -p 4000:4000 -e port=4000 node-build

优化如下:

  1. COPY . /server 放在 RUN npm install 之后,因为项目代码更频繁地变化,而依赖项相对稳定。