如何用GitHub Action缓存多阶段构建的共享Docker基础镜像?
解决方案:优化GitHub Action缓存共享Builder镜像
核心问题分析
你当前的配置混淆了Docker构建层缓存与共享Builder镜像缓存的作用:cache-from/to仅用于缓存Docker构建过程中的中间层,而ghcr.io/dancing-star/packages-image-full作为基础镜像,需要单独处理缓存逻辑,避免每次构建重新拉取。另外注意:环境变量BUILD_IMAGE_NAME的路径与Dockerfile中引用的镜像路径不一致,这会直接导致缓存失效,需先修正该拼写错误。
具体优化配置
1. 修改GitHub Action配置(.github/workflows/docky.yaml)
使用actions/cache缓存Builder镜像的tar包,避免重复从GHCR拉取;同时调整build-push-action的参数,确保复用本地已缓存的镜像:
name: Build Docker on: push: branches: [ main ] tags: - v* env: IMAGE_NAME: project-docker # 修正镜像路径,与Dockerfile保持一致 BUILDER_IMAGE: ghcr.io/dancing-star/packages-image-full:latest # 基于依赖锁文件生成缓存key,依赖更新时自动重新拉取镜像 BUILDER_IMAGE_CACHE_KEY: builder-image-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }} # 若不需要随依赖更新镜像,可使用固定key:builder-image-latest jobs: build: runs-on: ubuntu-latest permissions: packages: write contents: read steps: - name: Checkout uses: actions/checkout@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Login to GitHub Container Registry uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.DOCKER_DEPLOY_GITHUB }} # 将Builder镜像缓存到GitHub Actions缓存 - name: Cache Builder Image id: cache-builder uses: actions/cache@v3 with: path: /tmp/builder-image.tar key: ${{ env.BUILDER_IMAGE_CACHE_KEY }} # 缓存未命中时,拉取镜像并保存为tar包 - name: Pull and Save Builder Image if: steps.cache-builder.outputs.cache-hit != 'true' run: | docker pull ${{ env.BUILDER_IMAGE }} docker save -o /tmp/builder-image.tar ${{ env.BUILDER_IMAGE }} # 缓存命中时,加载本地tar包到Docker - name: Load Cached Builder Image if: steps.cache-builder.outputs.cache-hit == 'true' run: | docker load -i /tmp/builder-image.tar - name: Build and push uses: docker/build-push-action@v4 with: context: . file: Dockerfile push: true # 替换为你实际要推送的最终镜像标签 tags: ghcr.io/your-username/${{ env.IMAGE_NAME }}:latest # 保留构建层缓存,优化后续构建 cache-from: type=registry,ref=ghcr.io/your-username/${{ env.IMAGE_NAME }}:buildcache cache-to: type=registry,ref=ghcr.io/your-username/${{ env.IMAGE_NAME }}:buildcache,mode=max # 强制使用本地已有的Builder镜像,禁止重新拉取 pull: false
2. Dockerfile小优化
添加--mount=type=cache缓存npm临时文件,进一步压缩构建耗时:
FROM ghcr.io/dancing-star/packages-image-full:latest AS builder WORKDIR /var/dancing-star COPY . . # 挂载npm缓存目录,避免重复下载临时依赖 RUN --mount=type=cache,target=/tmp/node-cache \ npm config set cache /tmp/node-cache --global \ && npm run prod \ && rm -rf src FROM alpine WORKDIR /var/dancing-star # 简化COPY命令,提升可读性 COPY --from=builder /var/dancing-star/dist ./dist COPY --from=builder /var/dancing-star/assets ./assets COPY --from=builder /var/dancing-star/config ./config COPY --from=builder /var/dancing-star/scripts ./scripts COPY --from=builder /var/dancing-star/*.{json,md,js} ./ # CMD [ "pm2-runtime", "start", "app.pm2.json", "--env", "production" ]
关键优化点说明
- 单独缓存Builder镜像:通过
actions/cache将镜像保存为本地tar包,下次构建直接加载,省去远程拉取的时间。 - 路径一致性修正:确保环境变量与Dockerfile中的镜像地址完全匹配,避免缓存失效。
pull: false参数:强制Docker使用本地已有的基础镜像,不再发起远程拉取请求。- 分层缓存配合:构建层缓存(
cache-from/to)与基础镜像缓存分开配置,最大化优化构建效率。
内容的提问来源于stack exchange,提问作者Pian0_M4n
相关产品推荐
相关产品推荐

