diff --git a/_data/toc.yaml b/_data/toc.yaml index 45303e5c77..3106885593 100644 --- a/_data/toc.yaml +++ b/_data/toc.yaml @@ -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/ diff --git a/build/ci/github-actions/cache.md b/build/ci/github-actions/cache.md new file mode 100644 index 0000000000..04f1944dce --- /dev/null +++ b/build/ci/github-actions/cache.md @@ -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 %} diff --git a/build/ci/github-actions/configure-builder.md b/build/ci/github-actions/configure-builder.md index 46079d30ae..2a137f6ee3 100644 --- a/build/ci/github-actions/configure-builder.md +++ b/build/ci/github-actions/configure-builder.md @@ -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) diff --git a/build/ci/github-actions/copy-image-registries.md b/build/ci/github-actions/copy-image-registries.md new file mode 100644 index 0000000000..723a5c45a7 --- /dev/null +++ b/build/ci/github-actions/copy-image-registries.md @@ -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 %} diff --git a/build/ci/github-actions/examples.md b/build/ci/github-actions/examples.md deleted file mode 100644 index 9793a93760..0000000000 --- a/build/ci/github-actions/examples.md +++ /dev/null @@ -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 %} diff --git a/build/ci/github-actions/export-docker.md b/build/ci/github-actions/export-docker.md new file mode 100644 index 0000000000..96390db5be --- /dev/null +++ b/build/ci/github-actions/export-docker.md @@ -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 %} diff --git a/build/ci/github-actions/index.md b/build/ci/github-actions/index.md index bc79a5de2f..82a531cbbc 100644 --- a/build/ci/github-actions/index.md +++ b/build/ci/github-actions/index.md @@ -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). diff --git a/build/ci/github-actions/local-registry.md b/build/ci/github-actions/local-registry.md new file mode 100644 index 0000000000..53ee634b1a --- /dev/null +++ b/build/ci/github-actions/local-registry.md @@ -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 %} diff --git a/build/ci/github-actions/manage-tags-labels.md b/build/ci/github-actions/manage-tags-labels.md new file mode 100644 index 0000000000..b3180d5a25 --- /dev/null +++ b/build/ci/github-actions/manage-tags-labels.md @@ -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 %} diff --git a/build/ci/github-actions/multi-platform.md b/build/ci/github-actions/multi-platform.md new file mode 100644 index 0000000000..f28d3219c1 --- /dev/null +++ b/build/ci/github-actions/multi-platform.md @@ -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 %} diff --git a/build/ci/github-actions/named-contexts.md b/build/ci/github-actions/named-contexts.md new file mode 100644 index 0000000000..5364d44f75 --- /dev/null +++ b/build/ci/github-actions/named-contexts.md @@ -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 +``` diff --git a/build/ci/github-actions/push-multi-registries.md b/build/ci/github-actions/push-multi-registries.md new file mode 100644 index 0000000000..6d8b0caffe --- /dev/null +++ b/build/ci/github-actions/push-multi-registries.md @@ -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 %} diff --git a/build/ci/github-actions/secrets.md b/build/ci/github-actions/secrets.md new file mode 100644 index 0000000000..f21293303b --- /dev/null +++ b/build/ci/github-actions/secrets.md @@ -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. diff --git a/build/ci/github-actions/share-image-jobs.md b/build/ci/github-actions/share-image-jobs.md new file mode 100644 index 0000000000..228d30c23d --- /dev/null +++ b/build/ci/github-actions/share-image-jobs.md @@ -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 %} diff --git a/build/ci/github-actions/test-before-push.md b/build/ci/github-actions/test-before-push.md new file mode 100644 index 0000000000..a50f03757e --- /dev/null +++ b/build/ci/github-actions/test-before-push.md @@ -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`. diff --git a/build/ci/github-actions/update-dockerhub-desc.md b/build/ci/github-actions/update-dockerhub-desc.md new file mode 100644 index 0000000000..bac9449578 --- /dev/null +++ b/build/ci/github-actions/update-dockerhub-desc.md @@ -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 %}