Github Actions:如何在由 build-push-action 构建的 docker 镜像中运行容器化测试,而不会使执行时间加倍

Mar*_*rek 8 docker amazon-ecr github-actions

我正在Github Actions 中使用build-push-action (带有 buildx)来构建 Docker 映像并将其推送到 AWS ECR 注册表。在推送映像(不幸的是,它有几个 GB)之前,我想使用该映像来运行容器化的 Python 测试。

build-push-action有关于这个确切目标的文档- 他们的示例建议构建镜像,将其加载到 Docker,使用docker run ...然后推送。然而,虽然构建镜像(从下载的缓存)需要 7 分钟,但将其加载到 Docker 还需要 7 分钟——因此 CI 管道的时间增加了一倍。文档中的示例:


      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1
      - name: Build and export to Docker
        uses: docker/build-push-action@v2
        with:
          context: .
          load: true
          tags: ${{ env.TEST_TAG }}
      - name: Test
        run: |
          docker run --rm ${{ env.TEST_TAG }}
      - name: Build and push
        uses: docker/build-push-action@v2
        with:
          context: .
          platforms: linux/amd64,linux/arm64
          push: true
          tags: user/app:latest
Run Code Online (Sandbox Code Playgroud)

您是否知道有什么方法可以加快/缩短加载时间或如何docker run以其他方式在图像上运行?问题似乎在于,对于加载,图像首先导出到 tarball,然后加载到 docker,这不会通过任何类型的缓存加速。(将映像推送到 ECR 并将其拉回 docker 几乎更快。)但是,如果不加载,我无法获取映像。

在 Dockerfile 中运行测试是一种有效的快速解决方法。但接下来我们遇到了同样的问题 - 如何在不进行肮脏黑客攻击的情况下获得输出文件(例如覆盖率统计数据)。

谢谢。

为了完整起见,在我想要放置测试的地方添加我的真实示例:


- name: Login to Amazon ECR
  id: login-ecr
  uses: aws-actions/amazon-ecr-login@v1

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

- name: Build Image and Push to ECR
  uses: docker/build-push-action@v2
  env:
    ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
  with:
    context: .
    push: true
    build-args: |
      build_id=${{ github.sha }}
    tags: |
      ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:latest
    cache-from: type=registry,ref=${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:latest
    cache-to: type=inline

Run Code Online (Sandbox Code Playgroud)

Mar*_*rek 2

我的问题部分是基于对 BuildX 及其在示例工作流程中的作用的错误假设。(我认为你必须使用 BuildX 才能在操作中使用 BuildKit,并且我们的 Dockerfile 使用了一些 BuildKit 功能)

我在Docker BuildX image not shown in docker image ls博客文章 Multi-arch build and images, the simple way 中找到了部分问题的答案。

通过使用setup-buildx-action步骤,BuildKit 构建不会直接加载到 docker 中的多平台映像(因为您需要加载单平台映像)。我们目前不需要多平台构建,我们更喜欢 CI 的速度。因此,从工作流程中删除会setup-buildx-action导致单平台映像出现docker images,并且可以立即用于运行测试(将单平台映像加载到 docker 没有明显的时间开销)。

即注释掉这一步有帮助:

- name: Set up Docker Buildx
  uses: docker/setup-buildx-action@v1
Run Code Online (Sandbox Code Playgroud)

一旦我们的管道变得更加复杂和冗长,我们可能会再次开始构建多平台图像,但就目前而言,节省 6 分钟的运行时间更有意义。

注意:请随意添加您的答案/评论。我相信有一个比删除 buildx 设置更好的解决方案,而且我想知道是否有一个智能解决方案来构建多平台解决方案并快速加载图像docker images