You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker多阶段构建提速:GitLab CI中如何拉取旧镜像优化缓存?

复用Docker多阶段构建缓存的GitLab CI方案

完全可以通过Docker的--cache-from参数实现这个需求,利用容器仓库中已有的上一版本镜像作为构建缓存,大幅缩短多阶段构建的耗时。

核心原理

Docker的docker build命令支持通过--cache-from指定一个或多个远程镜像作为缓存源,构建过程中会检查这些镜像的层是否和当前构建的层匹配,匹配上的话就直接复用,不用重新执行对应阶段的构建步骤。

具体实现步骤

  1. 预拉取缓存镜像:在构建新镜像前,先尝试拉取仓库中已有的最新镜像,即使拉取失败(比如首次构建)也不中断流水线。
  2. 构建时指定缓存源:执行构建命令时,通过--cache-from参数指定刚才拉取的镜像,让Docker复用其中的层。
  3. 推送新镜像作为下一次缓存:构建完成后,将新镜像推送到仓库,作为下一次构建的缓存源。

GitLab CI示例配置

build-and-push-image:
  stage: build
  image: docker:latest
  services:
    - docker:dind
  script:
    # 登录容器仓库(GitLab Registry可通过内置变量自动认证)
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    # 尝试拉取最新镜像作为缓存,拉取不到不报错
    - docker pull $CI_REGISTRY_IMAGE:latest || true
    # 多阶段构建,指定缓存源为拉取的最新镜像
    - docker build 
        --cache-from $CI_REGISTRY_IMAGE:latest 
        -t $CI_REGISTRY_IMAGE:latest 
        -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .
    # 推送新镜像到仓库
    - docker push $CI_REGISTRY_IMAGE:latest
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA

进阶优化:多阶段精细化缓存

如果你的Dockerfile分为多个独立阶段(比如编译阶段、运行时阶段),可以给每个阶段单独打标签推送,构建时分别指定缓存源,进一步提升缓存复用效率:

假设你的Dockerfile是这样的:

# 编译阶段
FROM node:20 as builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# 运行时阶段
FROM nginx:alpine as runtime
COPY --from=builder /app/dist /usr/share/nginx/html

对应的CI脚本可以调整为:

script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    # 拉取编译阶段和运行时阶段的缓存镜像
    - docker pull $CI_REGISTRY_IMAGE:builder || true
    - docker pull $CI_REGISTRY_IMAGE:latest || true
    # 先构建并推送编译阶段镜像
    - docker build 
        --cache-from $CI_REGISTRY_IMAGE:builder 
        --target builder 
        -t $CI_REGISTRY_IMAGE:builder .
    - docker push $CI_REGISTRY_IMAGE:builder
    # 构建运行时镜像,同时复用编译阶段和旧运行时镜像的缓存
    - docker build 
        --cache-from $CI_REGISTRY_IMAGE:builder 
        --cache-from $CI_REGISTRY_IMAGE:latest 
        -t $CI_REGISTRY_IMAGE:latest .
    - docker push $CI_REGISTRY_IMAGE:latest

注意事项

  • 确保GitLab CI Runner拥有容器仓库的拉取和推送权限,使用GitLab Registry时可直接利用CI_REGISTRY_USER、CI_REGISTRY_PASSWORD等内置变量完成认证。
  • 如果构建过程中有一些非Docker层的依赖(比如npm包、Go模块),可以配合GitLab CI的cache机制缓存这些依赖,和Docker镜像缓存形成互补。

内容的提问来源于stack exchange,提问作者confusedandsad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 12:05:07