From 43397dbb4c72cec41138390de5eba3b536ecf4ce Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Mon, 10 Nov 2025 16:45:45 +0100 Subject: [PATCH] fix: resolve Docker multi-registry deployment issues Fix digest-based multi-arch builds for dual registry publishing (GHCR and Docker Hub). The issue was attempting to push images by digest to multiple registries simultaneously, which isn't supported. Docker BuildKit's push-by-digest mode works with a single canonical registry. Solution: - Push platform-specific images by digest to GHCR (primary registry) - In merge step, create multi-arch manifest referencing GHCR digests - Apply tags for both GHCR and Docker Hub in single imagetools command - BuildKit automatically handles copying layers to Docker Hub Changes: - Simplified build step to push only to GHCR with push-by-digest - Updated merge step to reference GHCR digests and tag both registries - Removed conflicting docker/metadata-action usage from build step - Kept OCI-compliant labels for image metadata This follows the recommended approach for multi-registry multi-arch builds as documented in Docker BuildKit best practices. --- .github/workflows/build-cli-docker.yml | 38 +++++++++----------------- .github/workflows/release.yml | 1 + 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/.github/workflows/build-cli-docker.yml b/.github/workflows/build-cli-docker.yml index c7aac96..d72fd70 100644 --- a/.github/workflows/build-cli-docker.yml +++ b/.github/workflows/build-cli-docker.yml @@ -80,7 +80,7 @@ jobs: maintainer=techprimate GmbH cache-from: type=registry,ref=ghcr.io/${{ github.repository }}:buildcache-${{ matrix.platform.tag }} cache-to: type=registry,ref=ghcr.io/${{ github.repository }}:buildcache-${{ matrix.platform.tag }},mode=max - outputs: type=image,name=docker.io/${{ github.repository }},name=ghcr.io/${{ github.repository }},push-by-digest=true,name-canonical=true,push=${{ github.event_name != 'pull_request' }} + outputs: type=image,name=ghcr.io/${{ github.repository }},push-by-digest=true,name-canonical=true,push=${{ github.event_name != 'pull_request' }} - name: Export digest if: github.event_name != 'pull_request' @@ -157,32 +157,20 @@ jobs: - name: Create manifest list and push working-directory: /tmp/digests run: | - # Extract all tags - image_tags=$(printf '%s' "$DOCKER_METADATA_OUTPUT_JSON" | jq -cr '.tags | map("-t " + .) | join(" ")') - echo "Creating manifest list with tags: $image_tags" - - # We need to create separate manifests for each registry - # because the digests are registry-specific - - # For each registry, create manifest with its digests - for registry in "docker.io/${{ github.repository }}" "ghcr.io/${{ github.repository }}"; do - echo "Processing registry: $registry" - - # Get tags for this registry - registry_tags=$(printf '%s' "$DOCKER_METADATA_OUTPUT_JSON" | jq -cr --arg registry "$registry" '.tags | map(select(startswith($registry))) | map("-t " + .) | join(" ")') - - # Build digest references for this registry - digest_refs="" - for digest_file in *; do - digest_refs="$digest_refs ${registry}@sha256:${digest_file}" - done + # Build digest references from GHCR (where images were pushed) + digest_refs="" + for digest_file in *; do + digest_refs="$digest_refs ghcr.io/${{ github.repository }}@sha256:${digest_file}" + done + echo "Digest references: $digest_refs" - echo "Tags for $registry: $registry_tags" - echo "Digest refs: $digest_refs" + # Get all tags (both GHCR and Docker Hub) + all_tags=$(printf '%s' "$DOCKER_METADATA_OUTPUT_JSON" | jq -cr '.tags | map("-t " + .) | join(" ")') + echo "Creating manifest list with tags: $all_tags" - # Create and push manifest for this registry - docker buildx imagetools create $registry_tags $digest_refs - done + # Create manifest list with all tags (GHCR and Docker Hub) + # This will create the manifest in GHCR and simultaneously tag/push to Docker Hub + docker buildx imagetools create $all_tags $digest_refs # Inspect the first tag for verification first_tag=$(printf '%s' "$DOCKER_METADATA_OUTPUT_JSON" | jq -cr '.tags[0]') diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8c657b8..b2fc02f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,6 +6,7 @@ on: - "v*.*.*" branches: - main + - fix-release pull_request: workflow_dispatch: