From 4815dc523f6b6eb03b22e1573ab4f20b9ad7be7c Mon Sep 17 00:00:00 2001 From: Tobias Gesellchen Date: Sat, 13 Jun 2026 23:06:04 +0200 Subject: [PATCH] Add multi-arch image workflow for the registry Add a dedicated workflow.dispatch workflow that builds and pushes a single multi-arch manifest (gesellix/registry:) spanning linux/amd64, linux/arm64 and Windows nanoserver ltsc2022 + ltsc2025. - image.yml: per-OS build jobs (Linux via buildx+QEMU, Windows native on matched runners) merged with docker buildx imagetools create. - Rework registry-windows/Dockerfile: the build stage used a Linux golang base with PowerShell/Windows syntax, which cannot build. Switch to golang windowsservercore (ships git + PowerShell) and parameterize the Windows base via WINDOWS_VERSION; nanoserver stays the runtime base. - Add registry-windows/Dockerfile.linux: same distribution source and include_oss/include_gcs build tags, cross-compiled per buildx target arch. - Pin ci.yml image-build to windows-2022 so the default ltsc2022 build runs under process isolation. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/ci.yml | 2 +- .github/workflows/image.yml | 86 +++++++++++++++++++++++++++++++ registry-windows/Dockerfile | 13 +++-- registry-windows/Dockerfile.linux | 29 +++++++++++ 4 files changed, 124 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/image.yml create mode 100644 registry-windows/Dockerfile.linux diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b957248..cbeba69 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,7 +57,7 @@ jobs: name: Test Results (Java ${{ matrix.java }} on ${{ matrix.os }}) path: '**/build/test-results/test/TEST-*.xml' image-build: - runs-on: windows-latest + runs-on: windows-2022 timeout-minutes: 20 steps: - uses: actions/checkout@v6 diff --git a/.github/workflows/image.yml b/.github/workflows/image.yml new file mode 100644 index 0000000..8805392 --- /dev/null +++ b/.github/workflows/image.yml @@ -0,0 +1,86 @@ +--- +name: Build and Push multi-arch image + +permissions: + contents: read + +on: + workflow_dispatch: + inputs: + image_tag: + description: 'Image tag to publish, e.g. 3.1.1' + required: true + type: string + +jobs: + build-publish-linux: + name: Build and Publish (Linux) + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + - name: Set up QEMU + uses: docker/setup-qemu-action@v4 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + - name: Login to Docker Hub + uses: docker/login-action@v4 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Build and Push image + uses: docker/build-push-action@v7 + with: + context: registry-windows + file: registry-windows/Dockerfile.linux + platforms: linux/amd64,linux/arm64 + push: true + tags: gesellix/registry:${{ inputs.image_tag }}-linux + + build-publish-windows: + name: Build and Publish (Windows ${{ matrix.windows_version }}) + strategy: + fail-fast: false + matrix: + include: + - windows_version: ltsc2022 + runner: windows-2022 + - windows_version: ltsc2025 + runner: windows-2025 + runs-on: ${{ matrix.runner }} + steps: + - name: Checkout + uses: actions/checkout@v6 + - name: Login to Docker Hub + uses: docker/login-action@v4 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Docker Build + run: | + docker build -f registry-windows/Dockerfile --build-arg WINDOWS_VERSION=${{ matrix.windows_version }} -t gesellix/registry:${{ inputs.image_tag }}-windows-${{ matrix.windows_version }} registry-windows + - name: Docker Push + run: | + docker push gesellix/registry:${{ inputs.image_tag }}-windows-${{ matrix.windows_version }} + + publish-manifest: + name: Publish Manifest + runs-on: ubuntu-latest + needs: + - build-publish-linux + - build-publish-windows + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + - name: Login to Docker Hub + uses: docker/login-action@v4 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Docker Manifest + run: | + docker buildx imagetools create -t gesellix/registry:${{ inputs.image_tag }} \ + gesellix/registry:${{ inputs.image_tag }}-linux \ + gesellix/registry:${{ inputs.image_tag }}-windows-ltsc2022 \ + gesellix/registry:${{ inputs.image_tag }}-windows-ltsc2025 +... diff --git a/registry-windows/Dockerfile b/registry-windows/Dockerfile index 64f2793..2c62db7 100644 --- a/registry-windows/Dockerfile +++ b/registry-windows/Dockerfile @@ -1,12 +1,15 @@ -FROM golang:1.26.4 AS build -#FROM golang:1.19.0-nanoserver AS build +ARG GO_VERSION=1.26.4 +ARG WINDOWS_VERSION=ltsc2022 +ARG DISTRIBUTION_VERSION=v3.1.1 + +FROM golang:${GO_VERSION}-windowsservercore-${WINDOWS_VERSION} AS build ENV GO111MODULE=auto SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] -ENV DOCKER_BUILDTAGS include_oss include_gcs -ENV DISTRIBUTION_VERSION v3.1.1 +ENV DOCKER_BUILDTAGS="include_oss include_gcs" +ARG DISTRIBUTION_VERSION RUN mkdir src\github.com\distribution ; \ cd src\github.com\distribution ; \ @@ -17,7 +20,7 @@ RUN mkdir src\github.com\distribution ; \ go build -o registry.exe ; \ dir -FROM mcr.microsoft.com/windows/nanoserver:ltsc2022 +FROM mcr.microsoft.com/windows/nanoserver:${WINDOWS_VERSION} EXPOSE 5000 ENTRYPOINT ["\\registry.exe"] diff --git a/registry-windows/Dockerfile.linux b/registry-windows/Dockerfile.linux new file mode 100644 index 0000000..4b6a8a1 --- /dev/null +++ b/registry-windows/Dockerfile.linux @@ -0,0 +1,29 @@ +ARG GO_VERSION=1.26.4 +ARG DISTRIBUTION_VERSION=v3.1.1 + +FROM --platform=$BUILDPLATFORM golang:${GO_VERSION} AS build + +ENV GO111MODULE=auto +ENV CGO_ENABLED=0 +ENV DOCKER_BUILDTAGS="include_oss include_gcs" + +ARG DISTRIBUTION_VERSION +ARG TARGETOS +ARG TARGETARCH + +RUN mkdir -p src/github.com/distribution \ + && cd src/github.com/distribution \ + && git clone -q https://github.com/distribution/distribution \ + && cd distribution \ + && git checkout -q "$DISTRIBUTION_VERSION" \ + && cd cmd/registry \ + && GOOS=$TARGETOS GOARCH=$TARGETARCH go build -o /registry + +FROM alpine:3.24.0 +EXPOSE 5000 + +ENTRYPOINT ["/registry"] +CMD ["serve", "/config/config.yml"] + +COPY --from=build /registry /registry +COPY config.yml /config/config.yml