33 KiB
| title | description | keywords |
|---|---|---|
| Example workflows | Docker GitHub Actions workflow examples. | CI, GitHub Actions, 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{: target="blank" rel="noopener" class="" } and push the image to both registries:
{% raw %}
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@v3
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{: 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{: target="blank" rel="noopener" class="" } to handle tags and labels based on GitHub Actions events and Git metadata:
{% raw %}
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@v3
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 using
the platforms option, as described in the following example.
Note
- For a list of available platforms, see the 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{: target="blank" rel="noopener" class="" } action.
{% raw %}
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@v3
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 for more details about cache storage backends.
Inline cache
In most cases you want to use the inline cache exporter.
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.
{% raw %}
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@v3
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.
{% raw %}
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@v3
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{: target="blank" rel="noopener" class="" } if you experience any issues. {: .warning }
The GitHub Actions cache exporter
backend uses the GitHub Cache API
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 %}
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@v3
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{:target="blank" rel="noopener" class=""}. The following example uses the
Move cachestep as a workaround (seemoby/buildkit#1896{:target="blank" rel="noopener" class=""} for more info). {: .warning }
You can also leverage GitHub cache using the actions/cache and local cache exporter with this action:
{% raw %}
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@v3
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{:target="blank" rel="noopener" class=""}
as provided by GitHub in your workflow.
First, create a Dockerfile that uses the secret:
# 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 %}
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@v3
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-filesinput:secret-files: | "MY_SECRET=./secret.txt"
If you're using GitHub 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 %}
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:
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@v3
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 %}
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@v3
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@v3
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ env.LATEST_TAG }}
{% endraw %}
Note
This workflow doesn't actually build the
linux/amd64image twice. The image is built once, and the following steps uses the internal cache for from the firstBuild and pushstep. The secondBuild and pushstep only buildslinux/arm64.
Local registry
For testing purposes you may need to create a local registry{: target="blank" rel="noopener" class="" } to push images into:
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@v3
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{: target="blank" rel="noopener" class="" }. However, you can pass data between jobs{: target="blank" rel="noopener" class="" } in a workflow using the actions/upload-artifact{: target="blank" rel="noopener" class="" } and actions/download-artifact{: target="blank" rel="noopener" class="" } actions:
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@v3
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,
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:
# syntax=docker/dockerfile:1
FROM alpine
RUN echo "Hello World"
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@v3
with:
context: .
build-contexts: |
alpine=docker-image://alpine:3.16
tags: myimage:latest
Use image in subsequent steps
By default, the 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:
# syntax=docker/dockerfile:1
FROM alpine
RUN echo "Hello World"
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@v3
with:
context: base
load: true
tags: my-base-image:latest
-
name: Build
uses: docker/build-push-action@v3
with:
context: .
build-contexts: |
alpine=docker-image://my-base-image:latest
tags: myimage:latest
Builder configuration
This section contains instructions on configuring your BuildKit build instances when using GitHub Actions.
Append additional nodes to the builder
Buildx supports running builds on multiple machines. This is useful for building multi-platform images on native nodes for more complicated cases that aren't handled by QEMU. Building on native nodes generally has better performance, and allows you to distribute the build across multiple machines.
You can append nodes to the builder you're creating using the append option.
It takes input in the form of a YAML string document to remove limitations
intrinsically linked to GitHub Actions: you can only use strings in the input
fields:
| Name | Type | Description |
|---|---|---|
name |
String | Name of the node. If empty, it's the name of the builder it belongs to, with an index number suffix. This is useful to set it if you want to modify/remove a node in an underlying step of you workflow. |
endpoint |
String | Docker context or endpoint of the node to add to the builder |
driver-opts |
List | List of additional driver-specific options |
buildkitd-flags |
String | Flags for buildkitd daemon |
platforms |
String | Fixed platforms for the node. If not empty, values take priority over the detected ones. |
Here is an example using remote nodes with the remote driver
and TLS authentication:
{% raw %}
name: ci
on:
push:
jobs:
buildx:
runs-on: ubuntu-latest
steps:
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
driver: remote
endpoint: tcp://oneprovider:1234
append: |
- endpoint: tcp://graviton2:1234
platforms: linux/arm64
- endpoint: tcp://linuxone:1234
platforms: linux/s390x
env:
BUILDER_NODE_0_AUTH_TLS_CACERT: ${{ secrets.ONEPROVIDER_CA }}
BUILDER_NODE_0_AUTH_TLS_CERT: ${{ secrets.ONEPROVIDER_CERT }}
BUILDER_NODE_0_AUTH_TLS_KEY: ${{ secrets.ONEPROVIDER_KEY }}
BUILDER_NODE_1_AUTH_TLS_CACERT: ${{ secrets.GRAVITON2_CA }}
BUILDER_NODE_1_AUTH_TLS_CERT: ${{ secrets.GRAVITON2_CERT }}
BUILDER_NODE_1_AUTH_TLS_KEY: ${{ secrets.GRAVITON2_KEY }}
BUILDER_NODE_2_AUTH_TLS_CACERT: ${{ secrets.LINUXONE_CA }}
BUILDER_NODE_2_AUTH_TLS_CERT: ${{ secrets.LINUXONE_CERT }}
BUILDER_NODE_2_AUTH_TLS_KEY: ${{ secrets.LINUXONE_KEY }}
{% endraw %}
Authentication for remote builders
The following examples show how to handle authentication for remote builders, using SSH or TLS.
SSH authentication
To be able to connect to an SSH endpoint using the docker-container driver,
you have to set up the SSH private key and configuration on the GitHub Runner:
{% raw %}
name: ci
on:
push:
jobs:
buildx:
runs-on: ubuntu-latest
steps:
-
name: Set up SSH
uses: MrSquaare/ssh-setup-action@523473d91581ccbf89565e12b40faba93f2708bd # v1.1.0
with:
host: graviton2
private-key: ${{ secrets.SSH_PRIVATE_KEY }}
private-key-name: aws_graviton2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
endpoint: ssh://me@graviton2
{% endraw %}
TLS authentication
You can also set up a remote BuildKit instance
using the remote driver. To ease the integration in your workflow, you can use
an environment variables that sets up authentication using the BuildKit client
certificates for the tcp://:
BUILDER_NODE_<idx>_AUTH_TLS_CACERTBUILDER_NODE_<idx>_AUTH_TLS_CERTBUILDER_NODE_<idx>_AUTH_TLS_KEY
The <idx> placeholder is the position of the node in the list of nodes.
{% raw %}
name: ci
on:
push:
jobs:
buildx:
runs-on: ubuntu-latest
steps:
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
driver: remote
endpoint: tcp://graviton2:1234
env:
BUILDER_NODE_0_AUTH_TLS_CACERT: ${{ secrets.GRAVITON2_CA }}
BUILDER_NODE_0_AUTH_TLS_CERT: ${{ secrets.GRAVITON2_CERT }}
BUILDER_NODE_0_AUTH_TLS_KEY: ${{ secrets.GRAVITON2_KEY }}
{% endraw %}
Daemon configuration
You can provide a BuildKit configuration
to your builder if you're using the docker-container driver
(default) with the config or config-inline inputs:
Registry mirror
You can configure a registry mirror using an inline block directly in your
workflow with the config-inline input:
name: ci
on:
push:
jobs:
buildx:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
config-inline: |
[registry."docker.io"]
mirrors = ["mirror.gcr.io"]
For more information about using a registry mirror, see Registry mirror.
Max parallelism
You can limit the parallelism of the BuildKit solver which is particularly useful for low-powered machines.
You can use the config-inline input like the previous example, or you can use
a dedicated BuildKit config file from your repository if you want with the
config input:
# .github/buildkitd.toml
[worker.oci]
max-parallelism = 4
name: ci
on:
push:
jobs:
buildx:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
config: .github/buildkitd.toml
Standalone mode
If you don't have the Docker CLI installed on the GitHub Runner, the Buildx
binary gets invoked directly, instead of calling it as a Docker CLI plugin. This
can be useful if you want to use the kubernetes driver in your self-hosted
runner:
name: ci
on:
push:
jobs:
buildx:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
driver: kubernetes
-
name: Build
run: |
buildx build .
Isolated builders
The following example shows how you can select different builders for different jobs.
An example scenario where this might be useful is when you are using a monorepo, and you want to pinpoint different packages to specific builders. For example, some packages may be particularly resource-intensive to build and require more compute. Or they require a builder equipped with a particular capability or hardware.
For more information about remote builder, see remote driver
and the append builder nodes example.
{% raw %}
name: ci
on:
push:
branches:
- "main"
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
uses: docker/setup-buildx-action@v2
id: builder1
-
uses: docker/setup-buildx-action@v2
id: builder2
-
name: Builder 1 name
run: echo ${{ steps.builder1.outputs.name }}
-
name: Builder 2 name
run: echo ${{ steps.builder2.outputs.name }}
-
name: Build against builder1
uses: docker/build-push-action@v3
with:
builder: ${{ steps.builder1.outputs.name }}
context: .
target: mytarget1
-
name: Build against builder2
uses: docker/build-push-action@v3
with:
builder: ${{ steps.builder2.outputs.name }}
context: .
target: mytarget2
{% endraw %}
Copy images between registries
Multi-platform images built using Buildx can
be copied from one registry to another using the buildx imagetools create command:
{% raw %}
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@v3
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{: target="blank" rel="noopener" class="" } with this action:
{% raw %}
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@v3
with:
context: .
push: true
tags: user/app:latest
-
name: Update repo description
uses: peter-evans/dockerhub-description@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
repository: user/app
{% endraw %}