首页 > 解决方案 > 如何使用 GitHub Actions 实现多阶段 Docker 构建?

问题描述

问题

我为我的容器构建了一个多阶段(两阶段)docker build,让我们命名它cont,我希望通过 GitHub Actions 实现自动化。构建过程的第一阶段/docker-image 很少更改并且构建需要很长时间;让我们称之为cont-build。我想通过不cont-build每次构建整个项目时都构建来减少构建持续时间。

在本地运行该构建时,我cont-build可以通过本地 docker 实例轻松获得该图像。我很难将这种简单的可用性转移到 GitHub Actions。

我检查了 Docker 和 GitHub 文档,但无法找到实现这一点的方法。在本地机器上它是如此简单,所以我认为在 GitHub-Actions 上它不会那么难......

方法

要保留cont-build图像,似乎有不同的方法

第二个对我来说似乎更直接,也不那么复杂。所以我的方法是发布cont-build到 DockerHub 并cont-build在每次我想构建时拉入 GitHub Action cont

我尝试使用uses: Docker://${{ secrets.DOCKERHUB_USERNAME }}/cont-build,但不知道在哪里放置它。

问题

在下面的工作流程中,我在哪里/如何提取“构建和推送”cont-build所需的图像?Dockerfile-cont另外,如果我的方法不好,多阶段构建的一般方法是什么,其中构建的一个阶段不会/很少更改,特别是考虑到 GitHub-caches 可能会在一段时间后被删除的事实?

我意识到我可以使用类似FROM mydockerID/cont-build:latestin 的东西Dockerfile-cont,但这似乎不是利用整个 GitHub-Workflow 环境的解决方案。这也意味着我必须以明文形式输入我的 docker-ID,而不是使用 GitHub-Secret。

name: CI for cont

on: workflow_dispatch

jobs:
  docker:
    runs-on: ubuntu-latest    
    steps:
      -
        name: Checkout
        uses: actions/checkout@v2      
      -
        name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1        
      -
        name: Login to DockerHub
        uses: docker/login-action@v1         
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      -
        name: Build and push
        id: docker_build
        uses: docker/build-push-action@v2     
        with:
          context: ./Code/
          file: ./Code/Dockerfile-cont
          push: true
          tags: ${{ secrets.DOCKERHUB_USERNAME }}/cont:latest
      -
        name: Image digest                  
        run: echo ${{ steps.docker_build.outputs.digest }}

标签: dockergithubgithub-actionsdockerhubdocker-multi-stage-build

解决方案


多阶段构建的问题在于,如果您想要缓存工作,您需要:

  1. 访问中间阶段以及重建的一部分。
  2. 用于--cache-from参考以前的图像,包括中间步骤。

如果您考虑重建将如何工作,如果您缺少中间阶段,则构建器将“嗯,我想我没有缓存中的那个”并重建;在完成之前的所有步骤之前,它无法判断最终阶段是否需要重建。

所以你需要做下面的歌舞,假设两个阶段,“构建”和运行时:

  1. 拉出“yourimage:latest”和“yourimage:build”。
  2. 构建并标记每个中间阶段,例如“yourimage:build”、“yourimage:latest”,使用--cache-from=yourimage:build --cache-from=yourimage:latest.
  3. 推送这两个图像。

您可以在https://pythonspeed.com/articles/faster-multi-stage-builds/上查看具体细节和更详细的解释以及示例解决方案


推荐阅读