docker - 如何使用 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
图像,似乎有不同的方法
- 使用某种 GitHub 缓存。我不确定图像缓存的持续时间。
- 从 DockerHub 中拉取镜像,在构建时间较长的情况下可能比构建快得多
第二个对我来说似乎更直接,也不那么复杂。所以我的方法是发布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:latest
in 的东西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 }}
解决方案
多阶段构建的问题在于,如果您想要缓存工作,您需要:
- 访问中间阶段以及重建的一部分。
- 用于
--cache-from
参考以前的图像,包括中间步骤。
如果您考虑重建将如何工作,如果您缺少中间阶段,则构建器将“嗯,我想我没有缓存中的那个”并重建;在完成之前的所有步骤之前,它无法判断最终阶段是否需要重建。
所以你需要做下面的歌舞,假设两个阶段,“构建”和运行时:
- 拉出“yourimage:latest”和“yourimage:build”。
- 构建并标记每个中间阶段,例如“yourimage:build”、“yourimage:latest”,使用
--cache-from=yourimage:build --cache-from=yourimage:latest
. - 推送这两个图像。
您可以在https://pythonspeed.com/articles/faster-multi-stage-builds/上查看具体细节和更详细的解释以及示例解决方案
推荐阅读
- python - 如果在 Windows 7 上同时运行,两个 python 应用程序会在一段时间后崩溃
- firebase - 创建 24 小时后删除 Firestore 文档
- c++ - 像 c# 中的 ConcurrentBag 一样,cpp(MFC) 中有哪些可用的选项?
- php - 如何对这个动态创建的表中的每一列求和,如 excel
- jenkins - Github jenkins webhook 集成失败
- ruby - Clojure 相当于 ruby 的#methods 方法?
- reactjs - React TypeScript:将 base64 字符串保存到 useState
- c# - 将 JSON 反序列化为 C# 对象
- lambda - 为什么 ConcurrentModificationException 在不安全操作之后不抛出,而是在整个 forEach 循环之后抛出?
- c++ - 我该如何解决这个错误,它的原因是什么?