CI 缓存构建层

CI 缓存构建层

为什么 Docker 构建缓存如此重要

每次 CI 构建都完整执行 Dockerfile 会导致:
– 构建时间长(尤其是有编译步骤的应用)
– 网络带宽浪费(重复下载依赖)
– CI 队列积压

利用 Docker 的层缓存机制可以大幅提速。

Docker 构建缓存原理

Docker 构建的每一层都是缓存单元。当某层指令和上下文未变化时,Docker 直接复用缓存层。

# 依赖层——变化频率低,应放在前面
FROM node:18 AS builder
WORKDIR /app
COPY package.json package-lock.json ./    # 只复制依赖文件
RUN npm ci --only=production              # 安装依赖(可缓存)
COPY . .                                  # 复制源码(变化频繁)
RUN npm run build

如果 package.json 没变,则 npm ci 层复用缓存,直接跳到 COPY . . 之后。

CI 中的缓存策略

策略一:–cache-from

# 从远程仓库拉取缓存
docker pull registry.example.com/myapp:latest || true

# 使用拉取的镜像作为缓存来源
docker build \
  --cache-from registry.example.com/myapp:latest \
  -t registry.example.com/myapp:${BUILD_TAG} .

策略二:BuildKit 缓存挂载

# syntax=docker/dockerfile:1
FROM golang:1.21 AS builder
WORKDIR /app
RUN --mount=type=cache,target=/root/.cache/go-build \
    go build -o /app/server .
FROM node:18
WORKDIR /app
RUN --mount=type=cache,target=/root/.npm \
    npm ci

策略三:共享缓存卷

# docker-compose CI 配置
services:
  builder:
    image: node:18
    volumes:
      - npm-cache:/root/.npm
      - .:/app
    working_dir: /app
    command: npm ci && npm run build

volumes:
  npm-cache:

不同语言的最佳缓存实践

语言 缓存目录 策略
Node.js /root/.npmnode_modules/.cache 先 copy package.json,安装后再 copy 源码
Go /root/.cache/go-build 使用 --mount=type=cache
Java/Maven /root/.m2 挂载 Maven 本地仓库
Python /root/.cache/pip 使用 pip cache
Rust /root/.cargotarget 使用 sccache 或 cargo chef

多阶段构建 + 缓存

# Stage 1: 依赖安装(低频变化)
FROM node:18 AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci

# Stage 2: 构建(高频变化)
FROM node:18 AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

# Stage 3: 运行(最小镜像)
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html

面试要点

  1. Docker 构建缓存基于指令哈希和上下文校验
  2. 将低频变化的指令放在 Dockerfile 前面
  3. BuildKit 的 --mount=type=cache 是高级缓存手段
  4. CI 中合理利用缓存可减少 50%-90% 的构建时间
  5. --cache-from 让远程构建也能享受缓存

面试官常问:你们在 CI 中用了哪些缓存技巧?构建时间优化了多少?

© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容