构建缓存策略
Docker 构建缓存可显著加速重复构建,下面介绍缓存原理与优化策略。
缓存原理
层缓存机制
dockerfile
FROM ubuntu:22.04 # 层1:基础镜像(缓存)
RUN apt-get update # 层2:更新包(缓存)
COPY package.json ./ # 层3:拷贝文件(文件变化破坏缓存)
RUN npm install # 层4:安装依赖(层3缓存失效时重建)
COPY . . # 层5:拷贝代码(代码变化破坏缓存)
某层缓存失效后,后续所有层都重建。
缓存判断
Docker 按以下顺序判断缓存:
- 指令相同
- 内容相同(文件内容、参数值)
- 前一层缓存有效
优化策略
按变化频率排序
dockerfile
# 推荐:变化少的指令在前
FROM node:18
WORKDIR /app
COPY package*.json ./ # 变化少
RUN npm install # 依赖变化才重建
COPY . . # 代码经常变化
RUN npm run build
dockerfile
# 错误:变化多的在前
FROM node:18
COPY . . # 代码变化破坏后续所有缓存
RUN npm install # 每次都重建
COPY package*.json ./
依赖与代码分离
dockerfile
# 分离依赖和代码
FROM node:18
WORKDIR /app
# 先拷贝依赖文件
COPY package*.json ./
RUN npm ci --only=production # 仅依赖变化时重建
# 再拷贝代码
COPY . .
RUN npm run build # 代码变化不影响依赖
缓存失效场景
强制重建
Bash
# 禁用缓存
docker build --no-cache -t my-app .
# 特定指令失效
# Dockerfile 中某指令变化,后续全部重建
基础镜像更新
dockerfile
# 基础镜像更新破坏所有缓存
FROM node:18 # 新版本发布后重建所有层
BuildKit 缓存
Bash
# 启用 BuildKit
export DOCKER_BUILDKIT=1
# 使用缓存挂载
RUN --mount=type=cache,target=/root/.npm \
npm install
# 缓存持久化,跨构建复用
BuildKit 特性
dockerfile
# syntax=docker/dockerfile:1
FROM node:18
# 缓存挂载
RUN --mount=type=cache,target=/root/.npm \
npm ci --only=production
# 安全密钥挂载
RUN --mount=type=secret,id=apikey \
cat /run/secrets/apikey
多阶段缓存
dockerfile
# 构建阶段缓存
FROM golang:1.21 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download # 缓存依赖下载
COPY . .
RUN go build # 代码变化不影响下载
# 运行阶段
FROM alpine:3.18
COPY --from=builder /app/myapp .
监控缓存
Bash
# 查看缓存使用
docker build -t my-app . 2>&1 | grep "CACHED"
# 输出
[+] Building 2.3s (8/8) FINISHED
=> [internal] load build context 0.1s
=> CACHED [1/5] FROM ubuntu:22.04
=> CACHED [2/5] RUN apt-get update
=> [3/5] COPY package.json ./
要点总结
- 缓存按层判断,某层失效后续全部重建
- 按变化频率排序 Dockerfile,变化少的指令在前
- 依赖与代码分离,避免代码变化影响依赖安装
- BuildKit 提供缓存挂载,跨构建复用
--no-cache强制重建,用于调试或基础镜像更新
📝 发现内容有误?点击此处直接编辑