docker/github-builder
GitHub: docker/github-builder
Docker 官方维护的可复用 GitHub Actions 工作流,用于安全、高效地构建容器镜像并自动生成 SLSA 来源证明。
Stars: 36 | Forks: 6
[](https://github.com/docker/github-builder/actions?workflow=.test-build)
[](https://github.com/docker/github-builder/actions?workflow=.test-bake)
* [概述](#overview)
* [核心优势](#key-advantages)
* [性能](#performance)
* [安全性](#security)
* [隔离性与可靠性](#isolation--reliability)
* [使用方法](#usage)
* [构建可复用工作流](#build-reusable-workflow)
* [输入](#inputs)
* [机密信息](#secrets)
* [Bake 可复用工作流](#bake-reusable-workflow)
* [输入](#inputs)
* [机密信息](#secrets)
## 概述
本仓库提供了由 Docker 官方维护的[可复用 GitHub Actions 工作流](https://docs.github.com/en/actions/how-tos/reuse-automations/reuse-workflows)
以使用 Docker 最佳实践安全地构建容器镜像和构件。
该可复用工作流整合了来自我们 GitHub Actions 的功能,例如
[`docker/build-push-action`](https://github.com/docker/build-push-action/)、
[`docker/metadata-action`](https://github.com/docker/metadata-action/) 等,
整合到单个工作流中:
```
name: ci
permissions:
contents: read
on:
push:
branches:
- 'main'
tags:
- 'v*'
pull_request:
build:
uses: docker/github-builder/.github/workflows/build.yml@v1
permissions:
contents: read # to fetch the repository content
id-token: write # for signing attestation(s) with GitHub OIDC Token
with:
output: image
push: ${{ github.event_name != 'pull_request' }}
meta-images: name/app
secrets:
registry-auths: |
- registry: docker.io
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
```
该工作流提供了一个受信的 BuildKit 实例,并生成符合 SLSA 标准的签名来源证明,保证构建源自源代码提交,且所有构建步骤均在来自不可变源的隔离沙盒环境中运行。这使得 GitHub 项目能够沿着一条无缝的路径迈向更高的安全性和信任级别。
## 核心优势
### 性能
* **多平台构建的原生并行化。**
工作流可以根据目标构建平台自动将构建分布到各个 runner 上,从而在不使用模拟或[自定义 CI 逻辑](https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners)
或自托管 runner 的情况下,提高其他架构的吞吐量。
* **优化的缓存预热与复用。**
构建器可以使用 GitHub Actions 缓存后端在分支、PR 和重建之间持久化层。这显著减少了冷启动时间,并避免了重复昂贵的依赖安装,即使对于外部贡献者的 Pull Request 也是如此。
* **集中化的构建配置。**
仓库不再需要配置 buildx 驱动、调整存储或资源限制。可复用工作流封装了推荐的配置,为任何选择加入的项目提供快速、一致的构建。
### 安全性
* **Docker 组织中的受信工作流。**
构建由 [**@docker**](https://github.com/docker)
组织中定义的可复用工作流执行,而不是由任意的用户定义工作流步骤执行。消费者可以依靠 GitHub 的信任模型和 Docker 侧的仓库保护(分支保护、代码审查、签名等)来推断谁控制着构建逻辑。
* **可验证、不可变的来源。**
工作流使用 GitHub OIDC token 和确切的 commit SHA 来获取源代码并将其绑定到 SLSA 来源证明中。这确保了构建与检入的仓库内容紧密相关——没有额外的 CI 步骤可以悄无声息地替换正在构建的内容。
* **为每次构建签名 SLSA 来源证明。**
BuildKit 生成符合 [SLSA 标准的来源证明](https://docs.docker.com/build/metadata/attestations/slsa-provenance/)
构件,这些构件使用绑定到 GitHub 工作流的身份进行签名。下游消费者可以验证:
- 哪个构建器提交生成了该镜像
- 哪个源代码提交生成了该镜像
- 哪个工作流和作业执行了构建
- 使用了哪些输入和构建参数
* **防止用户工作流篡改。**
构建步骤在可复用工作流中经过预定义和优化,无法被用户配置更改。这可以防止篡改:防止不受信任的工作流步骤修改构建逻辑、注入意外标志或产生误导性的来源证明。
### 隔离性与可靠性
* **用户 CI 逻辑与构建逻辑的分离。**
用户的工作流编排*何时*构建,而不是*如何*构建。
实际的构建步骤存在于 Docker 维护的可复用工作流中,
这些工作流不能从消费仓库中进行修改。
* **不可变、可复现的构建流水线。**
构建由声明式输入(仓库提交、构建配置、工作流版本)驱动。这带来了:
- 可复现性(相同的工作流 + 相同的输入 → 相同的输出)
- 可审计性(输入和工作流身份记录在来源证明中)
- 可靠性(减少对临时针对仓库的 CI 脚本的依赖)
* **减少 CI 差异性和配置漂移。**
通过复用相同的工作流,项目避免了为每个仓库维护自定义构建逻辑。缓存、来源证明、SBOM 生成和构建设置在所有采用者之间表现一致。
* **为下游消费者提供更高的保障。**
因为构件是由 [**@docker**](https://github.com/docker)
组织中的工作流生成的,并附带了 SLSA 来源证明,消费者可以在信任或推广镜像之前验证*源代码提交*和*构建器身份*,这是供应链加固的重要组成部分。
## 使用方法
### 构建可复用工作流
[`build.yml` 可复用工作流](.github/workflows/build.yml) 允许你
使用 Dockerfile 构建容器镜像和构件,其用户体验类似于
[`docker/build-push-action`](https://github.com/docker/build-push-action/)。
它提供了一个由 Docker 维护、具有特定风格的构建流水线,默认应用了安全性、性能和可靠性方面的最佳实践,包括隔离执行和签名的 SLSA 来源证明,同时保持每个仓库的配置最少化。
```
name: ci
permissions:
contents: read
on:
push:
branches:
- 'main'
tags:
- 'v*'
pull_request:
build:
uses: docker/github-builder/.github/workflows/build.yml@v1
permissions:
contents: read # to fetch the repository content
id-token: write # for signing attestation(s) with GitHub OIDC Token
with:
output: image
push: ${{ github.event_name != 'pull_request' }}
platforms: linux/amd64,linux/arm64
meta-images: name/app
meta-tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
secrets:
registry-auths: |
- registry: docker.io
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# Optional job to verify the pushed images' signatures. This is already done
# in the `build` job and can be omitted. It's provided here as an example of
# how to use the `verify.yml` reusable workflow.
build-verify:
uses: docker/github-builder/.github/workflows/verify.yml@v1
if: ${{ github.event_name != 'pull_request' }}
needs:
- build
with:
builder-outputs: ${{ toJSON(needs.build.outputs) }}
secrets:
registry-auths: |
- registry: docker.io
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
```
#### 输入
| Name | Type | Default | Description |
|------------------------|----------|--------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `runner` | String | `auto` | 用于构建的 [Ubuntu GitHub Hosted Runner](https://github.com/actions/runner-images?tab=readme-ov-file#available-images)(`auto`、`amd64`、`arm64` 之一)。`auto` runner 会根据目标 `platforms` 选择最匹配的 runner。如果你的构建不需要模拟(例如交叉编译),可以将其设置为 `amd64` |
| `distribute` | Bool | `true` | 是否将构建分布到多个 runner 上(每个 runner 构建一个平台) |
| `setup-qemu` | Bool | `false` | 运行 `setup-qemu-action` 步骤以安装 QEMU 静态二进制文件 |
| `artifact-name` | String | `docker-github-builder-assets` | 上传的 GitHub 构件的名称(用于 `local` 输出) |
| `artifact-upload` | Bool | `false` | 上传构建输出 GitHub 构件(用于 `local` 输出) |
| `annotations` | List | | 为镜像设置的注解列表(用于 `image` 输出) |
| `build-args` | List | `auto` | [构建时变量](https://docs.docker.com/engine/reference/commandline/buildx_build/#build-arg)列表。如果你想通过环境变量设置 build-arg,请使用 `envs` 输入 |
| `cache` | Bool | `false` | 启用 [GitHub Actions cache](https://docs.docker.com/build/cache/backends/gha/) 导出器 |
| `cache-scope` | String | target name or `buildkit` | 如果启用了 `cache`,该[作用域缓存对象所属](https://docs.docker.com/build/cache/backends/gha/#scope)的位置。这是在将缓存推送到 GitHub Actions 缓存后端时使用的缓存 blob 前缀名称 |
| `cache-mode` | String | `min` | 如果启用了缓存,要[导出的缓存层](https://docs.docker.com/build/cache/backends/#cache-mode)(`min` 或 `max`)。在 `min` 缓存模式下,只有导出到最终镜像中的层会被缓存,而在 `max` 缓存模式下,所有层都会被缓存,即使是中间步骤的层 |
| `context` | String | `.` | Git 工作树中用于构建的上下文 |
| `file` | String | `{context}/Dockerfile` | Dockerfile 的路径 |
| `labels` | List | | 镜像的标签列表(用于 `image` 输出) |
| `output` | String | | 构建输出目的地([`image`](https://docs.docker.com/build/exporters/image-registry/) 或 [`local`](https://docs.docker.com/build/exporters/local-tar/) 之一)。与 `build-push-action` 不同,它只接受 `image` 或 `local`。可复用工作流负责设置 `outputs` 属性 |
| `platforms` | List/CSV | | 要构建的[目标平台](https://docs.docker.com/engine/reference/commandline/buildx_build/#platform)列表 |
| `push` | Bool | `false` | 将镜像[推送](https://docs.docker.com/engine/reference/commandline/buildx_build/#push)到注册表(用于 `image` 输出) |
| `sbom` | Bool | `false` | 为构建生成 [SBOM](https://docs.docker.com/build/attestations/sbom/) 证明 |
| `shm-size` | String | | [`/dev/shm`](https://docs.docker.com/engine/reference/commandline/buildx_build/#shm-size) 的大小(例如 `2g`) |
| `sign` | String | `auto` | 为 `image` 输出签名证明清单,或为 `local` 输出签名构件,可以是 `auto`、`true` 或 `false` 之一。`auto` 模式下,如果启用了 `push` 以推送 `image`,或者启用了 `artifact-upload` 以上传 `local` 构建输出为 GitHub Artifact,则会启用签名 |
| `target` | String | | 设置要构建的目标阶段 |
| `ulimit` | List | | [Ulimit](https://docs.docker.com/engine/reference/commandline/buildx_build/#ulimit) 选项(例如 `nofile=1024:1024`) |
| `set-meta-annotations` | Bool | `false` | 附加由 `docker/metadata-action` 生成的 OCI Image Format Specification 注解 |
| `set-meta-labels` | Bool | `false` | 附加由 `docker/metadata-action` 生成的 OCI Image Format Specification 标签 |
| `meta-images` | List | | 用作标签基本名称的[镜像列表](https://github.com/docker/metadata-action?tab=readme-ov-file#images-input)(镜像输出必需) |
| `meta-tags` | List | | 作为键值对属性的[标签列表](https://github.com/docker/metadata-action?tab=readme-ov-file#tags-input) |
| `meta-flavor` | List | | [Flavor](https://github.com/docker/metadata-action?tab=readme-ov-file#flavor-input) 定义了 `meta-tags` 的全局行为 |
#### 机密信息
| Name | Default | Description |
|------------------|-----------------------|--------------------------------------------------------------------------------|
| `registry-auths` | | 对注册表的原始认证,定义为 YAML 对象(用于 `image` 输出) |
| `github-token` | `${{ github.token }}` | GitHub Token,用于针对仓库进行 Git 上下文的认证 |
### Bake 可复用工作流
[`bake.yml` 可复用工作流](.github/workflows/bake.yml) 允许你
使用 [Bake 定义](https://docs.docker.com/build/bake/)
构建容器镜像和构件,其用户体验类似于
[`docker/bake-action`](https://github.com/docker/bake-action/)。
它提供了一个由 Docker 维护、具有特定风格的构建流水线,默认应用了安全性、性能和可靠性方面的最佳实践,包括隔离执行和签名的 SLSA 来源证明,同时保持每个仓库的配置最少化。
```
name: ci
permissions:
contents: read
on:
push:
branches:
- 'main'
tags:
- 'v*'
pull_request:
bake:
uses: docker/github-builder/.github/workflows/bake.yml@v1
permissions:
contents: read # to fetch the repository content
id-token: write # for signing attestation(s) with GitHub OIDC Token
with:
output: image
push: ${{ github.event_name != 'pull_request' }}
meta-images: name/app
meta-tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
secrets:
registry-auths: |
- registry: docker.io
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# Optional job to verify the pushed images' signatures. This is already done
# in the `bake` job and can be omitted. It's provided here as an example of
# how to use the `verify.yml` reusable workflow.
bake-verify:
uses: docker/github-builder/.github/workflows/verify.yml@v1
if: ${{ github.event_name != 'pull_request' }}
needs:
- bake
with:
builder-outputs: ${{ toJSON(needs.bake.outputs) }}
secrets:
registry-auths: |
- registry: docker.io
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
```
#### 输入
| Name | Type | Default | Description |
|------------------------|--------|--------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `runner` | String | `auto` | 用于构建的 [Ubuntu GitHub Hosted Runner](https://github.com/actions/runner-images?tab=readme-ov-file#available-images)(`auto`、`amd64`、`arm64` 之一)。`auto` runner 会根据目标 `platforms` 选择最匹配的 runner。如果你的构建不需要模拟(例如交叉编译),可以将其设置为 `amd64` |
| `distribute` | Bool | `true` | 是否将构建分布到多个 runner 上(每个 runner 构建一个平台) |
| `setup-qemu` | Bool | `false` | 运行 `setup-qemu-action` 步骤以安装 QEMU 静态二进制文件 |
| `artifact-name` | String | `docker-github-builder-assets` | 上传的 GitHub 构件的名称(用于 `local` 输出) |
| `artifact-upload` | Bool | `false` | 上传构建输出 GitHub 构件(用于 `local` 输出) |
| `cache` | Bool | `false` | 启用 [GitHub Actions cache](https://docs.docker.com/build/cache/backends/gha/) 导出器 |
| `cache-scope` | String | target name or `buildkit` | 如果启用了 `cache`,该[作用域缓存对象所属](https://docs.docker.com/build/cache/backends/gha/#scope)的位置。这是在将缓存推送到 GitHub Actions 缓存后端时使用的缓存 blob 前缀名称 |
| `cache-mode` | String | `min` | 如果启用了缓存,要[导出的缓存层](https://docs.docker.com/build/cache/backends/#cache-mode)(`min` 或 `max`)。在 `min` 缓存模式下,只有导出到最终镜像中的层会被缓存,而在 `max` 缓存模式下,所有层都会被缓存,即使是中间步骤的层 |
| `context` | String | `.` | Git 工作树中用于构建的上下文 |
| `files` | List | `{context}/docker-bake.hcl` | Bake 定义文件列表 |
| `output` | String | | 构建输出目的地([`image`](https://docs.docker.com/build/exporters/image-registry/) 或 [`local`](https://docs.docker.com/build/exporters/local-tar/) 之一)。 |
| `push` | Bool | `false` | 将镜像推送到注册表(用于 `image` 输出) |
| `sbom` | Bool | `false` | 为构建生成 [SBOM](https://docs.docker.com/build/attestations/sbom/) 证明 |
| `set` | List | | 要覆盖的[目标值列表](https://docs.docker.com/engine/reference/commandline/buildx_bake/#set)(例如 `targetpattern.key=value`) |
| `sign` | String | `auto` | 为 `image` 输出签名证明清单,或为 `local` 输出签名构件,可以是 `auto`、`true` 或 `false` 之一。`auto` 模式下,如果启用了 `push` 以推送 `image`,或者启用了 `artifact-upload` 以上传 `local` 构建输出为 GitHub Artifact,则会启用签名 |
| `target` | String | `default` | 要构建的 Bake 目标 |
| `vars` | List | | 在 Bake 定义中设置的[变量](https://docs.docker.com/build/bake/variables/),以键值对列表形式 |
| `set-meta-annotations` | Bool | `false` | 附加由 `docker/metadata-action` 生成的 OCI Image Format Specification 注解 |
| `set-meta-labels` | Bool | `false` | 附加由 `docker/metadata-action` 生成的 OCI Image Format Specification 标签 |
| `meta-images` | List | | 用作标签基本名称的[镜像列表](https://github.com/docker/metadata-action?tab=readme-ov-file#images-input)(镜像输出必需) |
| `meta-tags` | List | | 作为键值对属性的[标签列表](https://github.com/docker/metadata-action?tab=readme-ov-file#tags-input) |
| `meta-labels` | List | | [自定义标签列表](https://github.com/docker/metadata-action?tab=readme-ov-file#overwrite-labels-and-annotations) |
| `meta-annotations` | List | | [自定义注解列表](https://github.com/docker/metadata-action?tab=readme-ov-file#overwrite-labels-and-annotations) |
| `meta-flavor` | List | | [Flavor](https://github.com/docker/metadata-action?tab=readme-ov-file#flavor-input) 定义了 `meta-tags` 的全局行为 |
#### 机密信息
| Name | Default | Description |
|------------------|-----------------------|--------------------------------------------------------------------------------|
| `registry-auths` | | 对注册表的原始认证,定义为 YAML 对象(用于 `image` 输出) |
| `github-token` | `${{ github.token }}` | GitHub Token,用于针对仓库进行 Git 上下文的认证 |
标签:BuildKit, DevSecOps, Docker, Docker Bake, GitHub Actions, GitHub OIDC, Google Gemini, SBOM, Web截图, 上游代理, 可复用工作流, 安全防御评估, 官方镜像, 容器安全, 容器镜像构建, 最佳实践, 特权提升, 硬件无关, 自动化部署, 自动笔记, 软件供应链, 镜像签名