Merge pull request #16765 from crazy-max/build-gha-update

build(gha): updates
This commit is contained in:
CrazyMax 2023-02-23 17:00:30 +01:00 committed by GitHub
commit 3689adec5c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 1070 additions and 934 deletions

View File

@ -1607,10 +1607,32 @@ manuals:
section:
- path: /build/ci/github-actions/
title: Introduction
- path: /build/ci/github-actions/examples/
title: Examples
- path: /build/ci/github-actions/configure-builder/
title: Configuring your builder
- path: /build/ci/github-actions/multi-platform/
title: Multi-platform image
- path: /build/ci/github-actions/secrets/
title: Secrets
- path: /build/ci/github-actions/push-multi-registries/
title: Push to multi-registries
- path: /build/ci/github-actions/manage-tags-labels/
title: Manage tags and labels
- path: /build/ci/github-actions/cache/
title: Cache management
- path: /build/ci/github-actions/export-docker/
title: Export to Docker
- path: /build/ci/github-actions/test-before-push/
title: Test before push
- path: /build/ci/github-actions/local-registry/
title: Local registry
- path: /build/ci/github-actions/share-image-jobs/
title: Share built image between jobs
- path: /build/ci/github-actions/named-contexts/
title: Named contexts
- path: /build/ci/github-actions/copy-image-registries/
title: Copy image between registries
- path: /build/ci/github-actions/update-dockerhub-desc/
title: Update Docker Hub repo description
- sectiontitle: Bake
section:
- path: /build/bake/

View File

@ -0,0 +1,218 @@
---
title: Cache management with GitHub Actions
keywords: ci, github actions, gha, buildkit, buildx, cache
---
This page contains examples on using the cache storage backends with GitHub
Actions.
> **Note**
>
> See [Cache storage backends](../../cache/backends/index.md) for more
> details about cache storage backends.
## Inline cache
In most cases you want to use the [inline cache exporter](../../cache/backends/inline.md).
However, note that the `inline` cache exporter only supports `min` cache mode.
To use `max` cache mode, push the image and the cache separately using the
registry cache exporter with the `cache-to` option, as shown in the [registry cache example](#registry-cache).
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
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.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: user/app:latest
cache-from: type=registry,ref=user/app:latest
cache-to: type=inline
```
{% endraw %}
## Registry cache
You can import/export cache from a cache manifest or (special) image
configuration on the registry with the [registry cache exporter](../../cache/backends/registry.md).
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
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.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: user/app:latest
cache-from: type=registry,ref=user/app:buildcache
cache-to: type=registry,ref=user/app:buildcache,mode=max
```
{% endraw %}
## GitHub cache
### Cache backend API
> Experimental
>
> This cache exporter is experimental. Please provide feedback on [BuildKit repository](https://github.com/moby/buildkit){:target="blank" rel="noopener" class=""}
> if you experience any issues.
{: .experimental }
The [GitHub Actions cache exporter](../../cache/backends/gha.md)
backend uses the [GitHub Cache API](https://github.com/tonistiigi/go-actions-cache/blob/master/api.md)
to fetch and upload cache blobs. That's why you should only use this cache
backend in a GitHub Action workflow, as the `url` (`$ACTIONS_CACHE_URL`) and
`token` (`$ACTIONS_RUNTIME_TOKEN`) attributes only get populated in a workflow
context.
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
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.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: user/app:latest
cache-from: type=gha
cache-to: type=gha,mode=max
```
{% endraw %}
### Local cache
> **Warning**
>
> At the moment, old cache entries aren't deleted, so the cache size [keeps growing](https://github.com/docker/build-push-action/issues/252){:target="blank" rel="noopener" class=""}.
> The following example uses the `Move cache` step as a workaround (see [`moby/buildkit#1896`](https://github.com/moby/buildkit/issues/1896){:target="blank" rel="noopener" class=""}
> for more info).
{: .warning }
You can also leverage [GitHub cache](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows){:target="blank" rel="noopener" class=""}
using the [actions/cache](https://github.com/actions/cache) and [local cache exporter](../../cache/backends/local.md)
with this action:
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Cache Docker layers
uses: actions/cache@v3
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
-
name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: user/app:latest
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
-
# Temp fix
# https://github.com/docker/build-push-action/issues/252
# https://github.com/moby/buildkit/issues/1896
name: Move cache
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
```
{% endraw %}

View File

@ -7,6 +7,32 @@ keywords: ci, github actions, gha, buildkit, buildx
This page contains instructions on configuring your BuildKit instances when
using our [Setup Buildx Action](https://github.com/docker/setup-buildx-action){:target="blank" rel="noopener" class=""}.
## Version pinning
By default, the action will attempt to use the latest version of [Buildx](https://github.com/docker/buildx){:target="blank" rel="noopener" class=""}
available on the GitHub Runner (the build client) and the latest release of
[BuildKit](https://github.com/moby/buildkit){:target="blank" rel="noopener" class=""} (the build server).
To pin to a specific version of Buildx, use the `version` input. For example,
to pin to Buildx v0.10.0:
```yaml
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
version: v0.10.0
```
To pin to a specific version of BuildKit, use the `image` option in the
`driver-opts` input. For example, to pin to BuildKit v0.11.0:
```yaml
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
driver-opts: image=moby/buildkit:v0.11.0
```
## BuildKit container logs
To display BuildKit container logs when using the `docker-container` driver,
@ -42,7 +68,7 @@ Logs will be available at the end of a job:
![BuildKit container logs](images/buildkit-container-logs.png)
## Daemon configuration
## BuildKit Daemon configuration
You can provide a [BuildKit configuration](../../buildkit/toml-configuration.md)
to your builder if you're using the [`docker-container` driver](../../drivers/docker-container.md)

View File

@ -0,0 +1,62 @@
---
title: Copy image between registries with GitHub Actions
keywords: ci, github actions, gha, buildkit, buildx, registry
---
[Multi-platform images](../../building/multi-platform.md) built using Buildx can
be copied from one registry to another using the [`buildx imagetools create` command](../../../engine/reference/commandline/buildx_imagetools_create.md):
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v4
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: |
user/app:latest
user/app:1.0.0
-
name: Push image to GHCR
run: |
docker buildx imagetools create \
--tag ghcr.io/user/app:latest \
--tag ghcr.io/user/app:1.0.0 \
user/app:latest
```
{% endraw %}

View File

@ -1,928 +0,0 @@
---
title: Example workflows
description: Docker GitHub Actions workflow examples.
keywords: ci, github actions, gha, examples
---
This page showcases different examples of how you can customize and use the
Docker GitHub Actions in your CI pipelines.
## Push to multi-registries
The following workflow will connect you to Docker Hub and [GitHub Container Registry](https://github.com/docker/login-action#github-container-registry){:target="blank" rel="noopener" class=""}
and push the image to both registries:
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v4
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: |
user/app:latest
user/app:1.0.0
ghcr.io/user/app:latest
ghcr.io/user/app:1.0.0
```
{% endraw %}
## Manage tags and labels
If you want an "automatic" tag management and [OCI Image Format Specification](https://github.com/opencontainers/image-spec/blob/master/annotations.md){:target="blank" rel="noopener" class=""}
for labels, you can do it in a dedicated setup step. The following workflow
will use the [Docker Metadata Action](https://github.com/docker/metadata-action){:target="blank" rel="noopener" class=""}
to handle tags and labels based on GitHub Actions events and Git metadata:
{% raw %}
```yaml
name: ci
on:
schedule:
- cron: "0 10 * * *"
push:
branches:
- "**"
tags:
- "v*.*.*"
pull_request:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Docker meta
id: meta
uses: docker/metadata-action@v4
with:
# list of Docker images to use as base name for tags
images: |
name/app
ghcr.io/username/app
# generate Docker tags based on the following events/attributes
tags: |
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Login to Docker Hub
if: github.event_name != 'pull_request'
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Login to GHCR
if: github.event_name != 'pull_request'
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
```
{% endraw %}
## Multi-platform images
You can build [multi-platform images](../../building/multi-platform.md) using
the `platforms` option, as described in the following example.
> **Note**
>
> - For a list of available platforms, see the [Docker Setup Buildx](https://github.com/marketplace/actions/docker-setup-buildx){:target="blank" rel="noopener" class=""}
> action.
> - If you want support for more platforms, you can use QEMU with the [Docker Setup QEMU](https://github.com/docker/setup-qemu-action){:target="blank" rel="noopener" class=""}
> action.
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v4
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: user/app:latest
```
{% endraw %}
## Cache
This page contains examples on using the cache storage backends with GitHub
actions.
> **Note**
>
> See [Cache storage backends](../../cache/backends/index.md) for more
> details about cache storage backends.
### Inline cache
In most cases you want to use the [inline cache exporter](../../cache/backends/inline.md).
However, note that the `inline` cache exporter only supports `min` cache mode.
To use `max` cache mode, push the image and the cache separately using the
registry cache exporter with the `cache-to` option, as shown in the [registry cache example](#registry-cache).
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
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.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: user/app:latest
cache-from: type=registry,ref=user/app:latest
cache-to: type=inline
```
{% endraw %}
### Registry cache
You can import/export cache from a cache manifest or (special) image
configuration on the registry with the [registry cache exporter](../../cache/backends/registry.md).
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
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.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: user/app:latest
cache-from: type=registry,ref=user/app:buildcache
cache-to: type=registry,ref=user/app:buildcache,mode=max
```
{% endraw %}
### GitHub cache
#### Cache backend API
> **Warning**
>
> This cache exporter is experimental. Please provide feedback on [BuildKit repository](https://github.com/moby/buildkit){:target="blank" rel="noopener" class=""}
> if you experience any issues.
{: .warning }
The [GitHub Actions cache exporter](../../cache/backends/gha.md)
backend uses the [GitHub Cache API](https://github.com/tonistiigi/go-actions-cache/blob/master/api.md)
to fetch and upload cache blobs. That's why you should only use this cache
backend in a GitHub Action workflow, as the `url` (`$ACTIONS_CACHE_URL`) and
`token` (`$ACTIONS_RUNTIME_TOKEN`) attributes only get populated in a workflow
context.
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
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.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: user/app:latest
cache-from: type=gha
cache-to: type=gha,mode=max
```
{% endraw %}
#### Local cache
> **Warning**
>
> At the moment, old cache entries aren't deleted, so the cache size [keeps growing](https://github.com/docker/build-push-action/issues/252){:target="blank" rel="noopener" class=""}.
> The following example uses the `Move cache` step as a workaround (see [`moby/buildkit#1896`](https://github.com/moby/buildkit/issues/1896){:target="blank" rel="noopener" class=""}
> for more info).
{: .warning }
You can also leverage [GitHub cache](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows){:target="blank" rel="noopener" class=""}
using the [actions/cache](https://github.com/actions/cache) and [local cache exporter](../../cache/backends/local.md)
with this action:
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Cache Docker layers
uses: actions/cache@v3
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
-
name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: user/app:latest
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
-
# Temp fix
# https://github.com/docker/build-push-action/issues/252
# https://github.com/moby/buildkit/issues/1896
name: Move cache
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
```
{% endraw %}
## Secrets
In the following example uses and exposes the [`GITHUB_TOKEN` secret](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#about-the-github_token-secret){:target="blank" rel="noopener" class=""}
as provided by GitHub in your workflow.
First, create a `Dockerfile` that uses the secret:
```dockerfile
# syntax=docker/dockerfile:1
FROM alpine
RUN --mount=type=secret,id=github_token \
cat /run/secrets/github_token
```
In this example, the secret name is `github_token`. The following workflow
exposes this secret using the `secrets` input:
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Build
uses: docker/build-push-action@v4
with:
context: .
platforms: linux/amd64,linux/arm64
tags: user/app:latest
secrets: |
"github_token=${{ secrets.GITHUB_TOKEN }}"
```
{% endraw %}
> **Note**
>
> You can also expose a secret file to the build with the `secret-files` input:
>
> ```yaml
> secret-files: |
> "MY_SECRET=./secret.txt"
> ```
If you're using [GitHub secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets){:target="blank" rel="noopener" class=""}
and need to handle multi-line value, you will need to place the key-value pair
between quotes:
{% raw %}
```yaml
secrets: |
"MYSECRET=${{ secrets.GPG_KEY }}"
GIT_AUTH_TOKEN=abcdefghi,jklmno=0123456789
"MYSECRET=aaaaaaaa
bbbbbbb
ccccccccc"
FOO=bar
"EMPTYLINE=aaaa
bbbb
ccc"
"JSON_SECRET={""key1"":""value1"",""key2"":""value2""}"
```
{% endraw %}
| Key | Value |
|------------------|-------------------------------------|
| `MYSECRET` | `***********************` |
| `GIT_AUTH_TOKEN` | `abcdefghi,jklmno=0123456789` |
| `MYSECRET` | `aaaaaaaa\nbbbbbbb\nccccccccc` |
| `FOO` | `bar` |
| `EMPTYLINE` | `aaaa\n\nbbbb\nccc` |
| `JSON_SECRET` | `{"key1":"value1","key2":"value2"}` |
> **Note**
>
> Double escapes are needed for quote signs.
## Export image to Docker
You may want your build result to be available in the Docker client through
`docker images` to be able to use it in another step of your workflow:
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Build
uses: docker/build-push-action@v4
with:
context: .
load: true
tags: myimage:latest
-
name: Inspect
run: |
docker image inspect myimage:latest
```
## Test your image before pushing it
In some cases, you might want to validate that the image works as expected
before pushing it.
The following workflow implements several steps to achieve this:
- Build and export the image to Docker
- Test your image
- Multi-platform build and push the image
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
env:
TEST_TAG: user/app:test
LATEST_TAG: user/app:latest
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and export to Docker
uses: docker/build-push-action@v4
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@v4
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ env.LATEST_TAG }}
```
{% endraw %}
> **Note**
>
> This workflow doesn't actually build the `linux/amd64` image twice. The image
> is built once, and the following steps uses the internal cache for from the
> first `Build and push` step. The second `Build and push` step only builds
> `linux/arm64`.
## Local registry
For testing purposes you may need to create a [local registry](https://hub.docker.com/_/registry){:target="blank" rel="noopener" class=""}
to push images into:
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
services:
registry:
image: registry:2
ports:
- 5000:5000
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
driver-opts: network=host
-
name: Build and push to local registry
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: localhost:5000/name/app:latest
-
name: Inspect
run: |
docker buildx imagetools inspect localhost:5000/name/app:latest
```
## Share built image between jobs
As each job is isolated in its own runner, you can't use your built image
between jobs, except if you're using [self-hosted runners](https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners){:target="blank" rel="noopener" class=""}
However, you can [pass data between jobs](https://docs.github.com/en/actions/using-workflows/storing-workflow-data-as-artifacts#passing-data-between-jobs-in-a-workflow){:target="blank" rel="noopener" class=""}
in a workflow using the [actions/upload-artifact](https://github.com/actions/upload-artifact){:target="blank" rel="noopener" class=""}
and [actions/download-artifact](https://github.com/actions/download-artifact){:target="blank" rel="noopener" class=""}
actions:
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
build:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Build and export
uses: docker/build-push-action@v4
with:
context: .
tags: myimage:latest
outputs: type=docker,dest=/tmp/myimage.tar
-
name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: myimage
path: /tmp/myimage.tar
use:
runs-on: ubuntu-latest
needs: build
steps:
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Download artifact
uses: actions/download-artifact@v3
with:
name: myimage
path: /tmp
-
name: Load image
run: |
docker load --input /tmp/myimage.tar
docker image ls -a
```
## Named contexts
You can define [additional build contexts](../../../engine/reference/commandline/buildx_build.md#build-context),
and access them in your Dockerfile with `FROM name` or `--from=name`. When
Dockerfile defines a stage with the same name it's overwritten.
This can be useful with GitHub Actions to reuse results from other builds or pin
an image to a specific tag in your workflow.
### Pin image to a tag
Replace `alpine:latest` with a pinned one:
```dockerfile
# syntax=docker/dockerfile:1
FROM alpine
RUN echo "Hello World"
```
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Build
uses: docker/build-push-action@v4
with:
context: .
build-contexts: |
alpine=docker-image://alpine:3.16
tags: myimage:latest
```
### Use image in subsequent steps
By default, the [Docker Setup Buildx](https://github.com/marketplace/actions/docker-setup-buildx){:target="blank" rel="noopener" class=""}
action uses `docker-container` as a build driver, so built Docker images aren't
loaded automatically.
With named contexts you can reuse the built image:
```dockerfile
# syntax=docker/dockerfile:1
FROM alpine
RUN echo "Hello World"
```
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Build base image
uses: docker/build-push-action@v4
with:
context: base
load: true
tags: my-base-image:latest
-
name: Build
uses: docker/build-push-action@v4
with:
context: .
build-contexts: |
alpine=docker-image://my-base-image:latest
tags: myimage:latest
```
## Copy images between registries
[Multi-platform images](../../building/multi-platform.md) built using Buildx can
be copied from one registry to another using the [`buildx imagetools create` command](../../../engine/reference/commandline/buildx_imagetools_create.md):
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v4
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: |
user/app:latest
user/app:1.0.0
-
name: Push image to GHCR
run: |
docker buildx imagetools create \
--tag ghcr.io/user/app:latest \
--tag ghcr.io/user/app:1.0.0 \
user/app:latest
```
{% endraw %}
## Update Docker Hub repository description
You can update the Docker Hub repository description using a third party action
called [Docker Hub Description](https://github.com/peter-evans/dockerhub-description){:target="blank" rel="noopener" class=""}
with this action:
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: user/app:latest
-
name: Update repo description
uses: peter-evans/dockerhub-description@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
repository: user/app
```
{% endraw %}

View File

@ -0,0 +1,40 @@
---
title: Export to Docker with GitHub Actions
keywords: ci, github actions, gha, buildkit, buildx, docker
---
You may want your build result to be available in the Docker client through
`docker images` to be able to use it in another step of your workflow:
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Build
uses: docker/build-push-action@v4
with:
context: .
load: true
tags: myimage:latest
-
name: Inspect
run: |
docker image inspect myimage:latest
```
{% endraw %}

View File

@ -42,6 +42,5 @@ using the official Docker actions, to build and push an image to Docker Hub.
There are many more things you can do to customize your workflow to better suit
your needs. To learn more about some of the more advanced use cases, take a look
at the advanced examples, such as [building multi-platform images](examples.md#multi-platform-images),
or [using cache storage backends](examples.md#cache) and also how to
[configure your builder](configure-builder.md).
at the advanced examples, such as [building multi-platform images](multi-platform.md),
or [using cache storage backends](cache.md) and also how to [configure your builder](configure-builder.md).

View File

@ -0,0 +1,50 @@
---
title: Local registry with GitHub Actions
keywords: ci, github actions, gha, buildkit, buildx, registry
---
For testing purposes you may need to create a [local registry](https://hub.docker.com/_/registry){:target="blank" rel="noopener" class=""}
to push images into:
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
services:
registry:
image: registry:2
ports:
- 5000:5000
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
driver-opts: network=host
-
name: Build and push to local registry
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: localhost:5000/name/app:latest
-
name: Inspect
run: |
docker buildx imagetools inspect localhost:5000/name/app:latest
```
{% endraw %}

View File

@ -0,0 +1,82 @@
---
title: Manage tags and labels with GitHub Actions
keywords: ci, github actions, gha, buildkit, buildx, tags, labels
---
If you want an "automatic" tag management and [OCI Image Format Specification](https://github.com/opencontainers/image-spec/blob/master/annotations.md){:target="blank" rel="noopener" class=""}
for labels, you can do it in a dedicated setup step. The following workflow
will use the [Docker Metadata Action](https://github.com/docker/metadata-action){:target="blank" rel="noopener" class=""}
to handle tags and labels based on GitHub Actions events and Git metadata:
{% raw %}
```yaml
name: ci
on:
schedule:
- cron: "0 10 * * *"
push:
branches:
- "**"
tags:
- "v*.*.*"
pull_request:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Docker meta
id: meta
uses: docker/metadata-action@v4
with:
# list of Docker images to use as base name for tags
images: |
name/app
ghcr.io/username/app
# generate Docker tags based on the following events/attributes
tags: |
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Login to Docker Hub
if: github.event_name != 'pull_request'
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Login to GHCR
if: github.event_name != 'pull_request'
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
```
{% endraw %}

View File

@ -0,0 +1,53 @@
---
title: Multi-platform image with GitHub Actions
keywords: ci, github actions, gha, buildkit, buildx, multi-platform
---
You can build [multi-platform images](../../building/multi-platform.md) using
the `platforms` option, as shown in the following example:
> **Note**
>
> - For a list of available platforms, see the [Docker Setup Buildx](https://github.com/marketplace/actions/docker-setup-buildx){:target="blank" rel="noopener" class=""}
> action.
> - If you want support for more platforms, you can use QEMU with the [Docker Setup QEMU](https://github.com/docker/setup-qemu-action){:target="blank" rel="noopener" class=""}
> action.
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v4
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: user/app:latest
```
{% endraw %}

View File

@ -0,0 +1,166 @@
---
title: Named contexts with GitHub Actions
keywords: ci, github actions, gha, buildkit, buildx, context
---
You can define [additional build contexts](../../../engine/reference/commandline/buildx_build.md#build-context),
and access them in your Dockerfile with `FROM name` or `--from=name`. When
Dockerfile defines a stage with the same name it's overwritten.
This can be useful with GitHub Actions to reuse results from other builds or pin
an image to a specific tag in your workflow.
## Pin image to a tag
Replace `alpine:latest` with a pinned one:
```dockerfile
# syntax=docker/dockerfile:1
FROM alpine
RUN echo "Hello World"
```
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Build
uses: docker/build-push-action@v4
with:
context: .
build-contexts: |
alpine=docker-image://alpine:3.16
tags: myimage:latest
```
{% endraw %}
## Use image in subsequent steps
By default, the [Docker Setup Buildx](https://github.com/marketplace/actions/docker-setup-buildx){:target="blank" rel="noopener" class=""}
action uses `docker-container` as a build driver, so built Docker images aren't
loaded automatically.
With named contexts you can reuse the built image:
```dockerfile
# syntax=docker/dockerfile:1
FROM alpine
RUN echo "Hello World"
```
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
driver: docker
-
name: Build base image
uses: docker/build-push-action@v4
with:
context: ./base
file: ./base/Dockerfile
load: true
tags: my-base-image:latest
-
name: Build
uses: docker/build-push-action@v4
with:
context: .
build-contexts: |
alpine=docker-image://my-base-image:latest
tags: myimage:latest
```
{% endraw %}
## Using with a container builder
As shown in the previous section we are not using the default
[`docker-container` driver](../../drivers/docker-container.md) for building with
named contexts. That's because this driver can't load an image from the Docker
store as it's isolated. To solve this problem you can use a [local registry](local-registry.md)
to push your base image in your workflow:
```dockerfile
# syntax=docker/dockerfile:1
FROM alpine
RUN echo "Hello World"
```
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
services:
registry:
image: registry:2
ports:
- 5000:5000
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
# network=host driver-opt needed to push to local registry
driver-opts: network=host
-
name: Build base image
uses: docker/build-push-action@v4
with:
context: ./base
file: ./base/Dockerfile
tags: localhost:5000/my-base-image:latest
push: true
-
name: Build
uses: docker/build-push-action@v4
with:
context: .
build-contexts: |
alpine=docker-image://localhost:5000/my-base-image:latest
tags: myimage:latest
```

View File

@ -0,0 +1,57 @@
---
title: Push to multi-registries with GitHub Actions
keywords: ci, github actions, gha, buildkit, buildx, registry
---
The following workflow will connect you to Docker Hub and [GitHub Container Registry](https://github.com/docker/login-action#github-container-registry){:target="blank" rel="noopener" class=""}
and push the image to both registries:
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v4
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: |
user/app:latest
user/app:1.0.0
ghcr.io/user/app:latest
ghcr.io/user/app:1.0.0
```
{% endraw %}

View File

@ -0,0 +1,97 @@
---
title: Using secrets with GitHub Actions
keywords: ci, github actions, gha, buildkit, buildx, secret
---
In the following example uses and exposes the [`GITHUB_TOKEN` secret](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#about-the-github_token-secret){:target="blank" rel="noopener" class=""}
as provided by GitHub in your workflow.
First, create a `Dockerfile` that uses the secret:
```dockerfile
# syntax=docker/dockerfile:1
FROM alpine
RUN --mount=type=secret,id=github_token \
cat /run/secrets/github_token
```
In this example, the secret name is `github_token`. The following workflow
exposes this secret using the `secrets` input:
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Build
uses: docker/build-push-action@v4
with:
context: .
platforms: linux/amd64,linux/arm64
tags: user/app:latest
secrets: |
"github_token=${{ secrets.GITHUB_TOKEN }}"
```
{% endraw %}
> **Note**
>
> You can also expose a secret file to the build with the `secret-files` input:
>
> ```yaml
> secret-files: |
> "MY_SECRET=./secret.txt"
> ```
If you're using [GitHub secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets){:target="blank" rel="noopener" class=""}
and need to handle multi-line value, you will need to place the key-value pair
between quotes:
{% raw %}
```yaml
secrets: |
"MYSECRET=${{ secrets.GPG_KEY }}"
GIT_AUTH_TOKEN=abcdefghi,jklmno=0123456789
"MYSECRET=aaaaaaaa
bbbbbbb
ccccccccc"
FOO=bar
"EMPTYLINE=aaaa
bbbb
ccc"
"JSON_SECRET={""key1"":""value1"",""key2"":""value2""}"
```
{% endraw %}
| Key | Value |
|------------------|-------------------------------------|
| `MYSECRET` | `***********************` |
| `GIT_AUTH_TOKEN` | `abcdefghi,jklmno=0123456789` |
| `MYSECRET` | `aaaaaaaa\nbbbbbbb\nccccccccc` |
| `FOO` | `bar` |
| `EMPTYLINE` | `aaaa\n\nbbbb\nccc` |
| `JSON_SECRET` | `{"key1":"value1","key2":"value2"}` |
> **Note**
>
> Double escapes are needed for quote signs.

View File

@ -0,0 +1,65 @@
---
title: Share built image between jobs with GitHub Actions
keywords: ci, github actions, gha, buildkit, buildx
---
As each job is isolated in its own runner, you can't use your built image
between jobs, except if you're using [self-hosted runners](https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners){:target="blank" rel="noopener" class=""}
However, you can [pass data between jobs](https://docs.github.com/en/actions/using-workflows/storing-workflow-data-as-artifacts#passing-data-between-jobs-in-a-workflow){:target="blank" rel="noopener" class=""}
in a workflow using the [actions/upload-artifact](https://github.com/actions/upload-artifact){:target="blank" rel="noopener" class=""}
and [actions/download-artifact](https://github.com/actions/download-artifact){:target="blank" rel="noopener" class=""}
actions:
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
build:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Build and export
uses: docker/build-push-action@v4
with:
context: .
tags: myimage:latest
outputs: type=docker,dest=/tmp/myimage.tar
-
name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: myimage
path: /tmp/myimage.tar
use:
runs-on: ubuntu-latest
needs: build
steps:
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Download artifact
uses: actions/download-artifact@v3
with:
name: myimage
path: /tmp
-
name: Load image
run: |
docker load --input /tmp/myimage.tar
docker image ls -a
```
{% endraw %}

View File

@ -0,0 +1,74 @@
---
title: Test before push with GitHub Actions
keywords: ci, github actions, gha, buildkit, buildx, test
---
In some cases, you might want to validate that the image works as expected
before pushing it.
The following workflow implements several steps to achieve this:
1. Build and export the image to Docker
2. Test your image
3. Multi-platform build and push the image
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
env:
TEST_TAG: user/app:test
LATEST_TAG: user/app:latest
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and export to Docker
uses: docker/build-push-action@v4
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@v4
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ env.LATEST_TAG }}
```
{% endraw %}
> **Note**
>
> This workflow doesn't actually build the `linux/amd64` image twice. The image
> is built once, and the following steps uses the internal cache for from the
> first `Build and push` step. The second `Build and push` step only builds
> `linux/arm64`.

View File

@ -0,0 +1,53 @@
---
title: Update Docker Hub repo description with GitHub Actions
keywords: ci, github actions, gha, buildkit, buildx, docker hub
---
You can update the Docker Hub repository description using a third party action
called [Docker Hub Description](https://github.com/peter-evans/dockerhub-description){:target="blank" rel="noopener" class=""}
with this action:
{% raw %}
```yaml
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: user/app:latest
-
name: Update repo description
uses: peter-evans/dockerhub-description@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
repository: user/app
```
{% endraw %}