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

如何在Google Cloud Builder中缓存Docker多阶段构建及构建步骤

我来帮你梳理下在GCP Cloud Build里实现构建步骤缓存(比如Go的/vendor依赖)+ 最终镜像缓存的最简单方案,结合你现有的Docker多阶段构建和Cloud Build配置来调整:

核心思路

要同时缓存最终镜像和构建阶段的依赖,关键是利用Docker分层缓存特性和Cloud Build的镜像缓存机制,让依赖下载层被重复利用,而不是每次构建都重新拉取。

第一步:优化你的Dockerfile(针对依赖缓存)

你的原Dockerfile里,先执行了go get再复制代码,这会导致每次代码变动时,依赖层也会重新构建。我们调整顺序,先复制依赖配置文件,再下载依赖,最后复制代码:

# 构建阶段(命名为builder,方便后续引用)
FROM golang:1.7.3 AS builder
WORKDIR /go/src/github.com/alexellis/href-counter/

# 1. 先复制依赖管理文件(如果用dep,就是Gopkg.toml和Gopkg.lock)
COPY Gopkg.toml Gopkg.lock ./
# 下载依赖并安装dep(如果还没装的话)
RUN go get -u github.com/golang/dep/cmd/dep && dep ensure -v

# 2. 再复制应用代码
COPY app.go .
# 执行构建
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

# 最终镜像阶段
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]

这样调整后,只要Gopkg.toml和Gopkg.lock不变,依赖下载的这一层就会被Docker缓存,不会每次都重新拉取/vendor依赖。

第二步:修改Cloud Build配置,缓存构建阶段镜像

你的原cloudbuild.yml已经在缓存最终镜像,但还需要缓存构建阶段的builder镜像,这样下次构建时可以直接复用builder里的依赖层。修改后的配置如下:

steps:
  # 先拉取所有可能的缓存镜像(包括builder和最终镜像)
  - name: 'gcr.io/cloud-builders/docker'
    args: ['pull', 'gcr.io/$PROJECT_ID/app-builder:$BRANCH_NAME']
  - name: 'gcr.io/cloud-builders/docker'
    args: ['pull', 'gcr.io/$PROJECT_ID/app-builder:latest']
  - name: 'gcr.io/cloud-builders/docker'
    args: ['pull', 'gcr.io/$PROJECT_ID/app:$BRANCH_NAME']
  - name: 'gcr.io/cloud-builders/docker'
    args: ['pull', 'gcr.io/$PROJECT_ID/app:latest']

  # 构建时指定多个缓存来源,包括builder镜像
  - name: 'gcr.io/cloud-builders/docker'
    args: [
      'build',
      '--cache-from', 'gcr.io/$PROJECT_ID/app-builder:latest',
      '--cache-from', 'gcr.io/$PROJECT_ID/app-builder:$BRANCH_NAME',
      '--cache-from', 'gcr.io/$PROJECT_ID/app:latest',
      '--cache-from', 'gcr.io/$PROJECT_ID/app:$BRANCH_NAME',
      '--build-arg', 'COMMIT_HASH=$COMMIT_SHA',
      '-t', 'gcr.io/$PROJECT_ID/app:$COMMIT_SHA',
      '-t', 'gcr.io/$PROJECT_ID/app-builder:$COMMIT_SHA', # 给builder镜像打标签
      '-f', 'config/dockerfiles/app.dockerfile',
      '.'
    ]

  # 给镜像打分支和latest标签
  - name: 'gcr.io/cloud-builders/docker'
    args: ["tag", "gcr.io/$PROJECT_ID/app:$COMMIT_SHA", "gcr.io/$PROJECT_ID/app:$BRANCH_NAME"]
  - name: 'gcr.io/cloud-builders/docker'
    args: ["tag", "gcr.io/$PROJECT_ID/app:$COMMIT_SHA", "gcr.io/$PROJECT_ID/app:latest"]
  - name: 'gcr.io/cloud-builders/docker'
    args: ["tag", "gcr.io/$PROJECT_ID/app-builder:$COMMIT_SHA", "gcr.io/$PROJECT_ID/app-builder:$BRANCH_NAME"]
  - name: 'gcr.io/cloud-builders/docker'
    args: ["tag", "gcr.io/$PROJECT_ID/app-builder:$COMMIT_SHA", "gcr.io/$PROJECT_ID/app-builder:latest"]

# 推送所有镜像(包括builder缓存镜像)到GCR
images:
  - 'gcr.io/$PROJECT_ID/app:$COMMIT_SHA'
  - 'gcr.io/$PROJECT_ID/app:$BRANCH_NAME'
  - 'gcr.io/$PROJECT_ID/app:latest'
  - 'gcr.io/$PROJECT_ID/app-builder:$COMMIT_SHA'
  - 'gcr.io/$PROJECT_ID/app-builder:$BRANCH_NAME'
  - 'gcr.io/$PROJECT_ID/app-builder:latest'

可选:用Cloud Build缓存卷进一步加速

如果想让依赖缓存更持久(比如跨不同分支构建复用),可以在cloudbuild.yml里添加缓存卷,挂载到Go的依赖缓存目录:

# 在cloudbuild.yml末尾添加
options:
  caching_options:
    cache_size: '10GB' # 按需调整大小
  volumes:
    - name: go-mod-cache
      path: /go/pkg/mod # Go Modules的缓存目录,如果是dep的话是/vendor或者GOPATH下的对应目录

这个卷会在Cloud Build的构建之间保留,即使Docker镜像缓存失效,也能直接复用本地的依赖缓存。

为什么这是最简单的方式?

  • 不需要额外的服务或工具,完全基于Docker和Cloud Build的原生特性
  • 只需要调整Dockerfile的步骤顺序和Cloud Build的镜像标签/缓存参数,改动很小
  • 同时覆盖了依赖层缓存和最终镜像缓存,构建速度提升明显

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:39:10