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

Github Actions中Docker镜像重复构建的流水线优化求助

问题描述

我刚用Github Actions搭建了一条流水线,步骤为:构建Docker应用 → 运行测试 → 发布至Docker镜像仓库。但测试与发布是两个独立Job,导致Docker镜像被重复构建两次。该镜像是Ruby-On-Rails应用,bundle install每次耗时2-3分钟,严重拖慢流水线速度。

我曾尝试在docker/build-push-action@v3中添加cache-from: type=gha和cache-to: type=gha,mode=max来加速构建,但出现报错:

Error: buildx failed with: ERROR: cache export feature is currently not supported for docker driver. Please switch to a different driver (eg. "docker buildx create --use")

请问如何修改流水线以缩短耗时?

原工作流代码:

name: Test & Publish Docker Image

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  run_application_tests:
    name: Run test suite
    runs-on: ubuntu-latest
    env:
      COMPOSE_FILE: docker-compose.yml
      DOCKER_USER: ${{ secrets.DOCKER_USER }}
      DOCKER_PASS: ${{ secrets.DOCKER_PASS }}

    steps:
    - name: Checkout code
      uses: actions/checkout@v3

    - name: Login To Docker Hub
      uses: docker/login-action@v2
      with:
        username: ${{ secrets.DOCKER_USERNAME }}
        password: ${{ secrets.DOCKER_PASSWORD }}

    - name: Build and run docker image
      run: docker-compose up -d --build

    - name: Run migrations
      run: make migrate

    - name: Run tests
      run: make test

  build_and_publish_docker_image:
    needs: run_application_tests
    name: Build & Publish Docker Images
    runs-on: ubuntu-latest
    steps:
    - name: Checkout The Repo
      uses: actions/checkout@v3
    
    - name: Login To Docker Hub
      uses: docker/login-action@v2
      with:
        username: ${{ secrets.DOCKER_USERNAME }}
        password: ${{ secrets.DOCKER_PASSWORD }}

    - name: Build & Push Docker Image
      uses: docker/build-push-action@v3
      with:
        push: true
        tags: |
          me/image:latest
          me/image:${{ github.sha }}
解决方案

1. 解决Buildx缓存报错:切换支持缓存的驱动

Github Actions默认Docker驱动不支持Buildx缓存导出功能,需先初始化Buildx专用驱动:
在使用docker/build-push-action前添加以下步骤:

- name: Set up Docker Buildx
  uses: docker/setup-buildx-action@v2

该步骤会自动创建并启用支持缓存的Buildx驱动,解决之前的报错。

2. 跨Job复用镜像,避免重复构建

将构建逻辑与测试合并为一个Job,同时利用GHA缓存让发布Job直接复用构建层,无需重新执行bundle install:

  • 测试Job中先构建带缓存的镜像,再用该镜像运行测试
  • 发布Job从GHA缓存拉取镜像层,仅执行推送操作

3. 优化Dockerfile的分层缓存

在Dockerfile中调整bundle install的位置,利用Docker分层缓存减少依赖安装次数:

# 先复制Gemfile相关文件,仅当Gemfile变更时才重新执行bundle install
COPY Gemfile Gemfile.lock ./
RUN bundle install --jobs 4 --retry 3

# 再复制项目其他代码
COPY . .
修改后的完整工作流代码
name: Test & Publish Docker Image

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  build_and_test:
    name: Build image & run tests
    runs-on: ubuntu-latest
    env:
      COMPOSE_FILE: docker-compose.yml
    steps:
    - name: Checkout code
      uses: actions/checkout@v3

    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v2

    - name: Login To Docker Hub
      uses: docker/login-action@v2
      with:
        username: ${{ secrets.DOCKER_USERNAME }}
        password: ${{ secrets.DOCKER_PASSWORD }}

    - name: Build Docker image with cache
      uses: docker/build-push-action@v3
      with:
        context: .
        load: true # 将构建好的镜像加载到本地Docker,用于测试
        tags: me/image:test-${{ github.sha }}
        cache-from: type=gha
        cache-to: type=gha,mode=max

    - name: Update docker-compose to use test image
      run: |
        sed -i 's/image: me\/image:latest/image: me\/image:test-${{ github.sha }}/' docker-compose.yml

    - name: Start application & run migrations
      run: |
        docker-compose up -d
        make migrate

    - name: Run tests
      run: make test

  publish_image:
    needs: build_and_test
    name: Publish Docker Images
    runs-on: ubuntu-latest
    steps:
    - name: Checkout The Repo
      uses: actions/checkout@v3

    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v2

    - name: Login To Docker Hub
      uses: docker/login-action@v2
      with:
        username: ${{ secrets.DOCKER_USERNAME }}
        password: ${{ secrets.DOCKER_PASSWORD }}

    - name: Push Docker Image (use cache)
      uses: docker/build-push-action@v3
      with:
        push: true
        tags: |
          me/image:latest
          me/image:${{ github.sha }}
        cache-from: type=gha
关键改动说明
  • 合并构建与测试Job,避免第一次构建资源浪费
  • 两个Job均添加docker/setup-buildx-action,解决Buildx缓存驱动问题
  • 发布Job直接从GHA缓存拉取镜像层,跳过耗时的bundle install步骤
  • Dockerfile分层优化,进一步减少依赖重复安装次数

内容的提问来源于stack exchange,提问作者A. Vreeswijk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 10:25:15