From f629507537707478c7a948760964b74b3ac54200 Mon Sep 17 00:00:00 2001 From: Zed Date: Sun, 7 Jun 2026 01:02:47 +0200 Subject: [PATCH] Publish a single multi-arch Docker image Build amd64 and arm64 natively (no emulation), push each by digest, then merge them into one multi-arch manifest so `zedeus/nitter:latest` and `:` resolve to the right image on any CPU. Replaces the separate `latest-arm64` tag, which is no longer needed. Update the README notes accordingly. --- .github/workflows/build-docker.yml | 120 +++++++++++++++++++++-------- README.md | 4 +- 2 files changed, 88 insertions(+), 36 deletions(-) diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index 9a6c490..f50cad7 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -7,55 +7,109 @@ on: branches: - master +env: + IMAGE: zedeus/nitter + jobs: tests: uses: ./.github/workflows/run-tests.yml secrets: inherit - build-docker-amd64: + # Build each architecture natively (no emulation) and push by digest only. + # The digests are stitched into a single multi-arch tag by the merge job. + build: needs: [tests] + strategy: + fail-fast: false + matrix: + include: + - runner: ubuntu-24.04 + platform: linux/amd64 + - runner: ubuntu-24.04-arm + platform: linux/arm64 + runs-on: ${{ matrix.runner }} + steps: + - name: Prepare platform name + run: echo "PLATFORM_PAIR=${platform//\//-}" >> "$GITHUB_ENV" + env: + platform: ${{ matrix.platform }} + + - uses: actions/checkout@v6 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + version: latest + + - name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and push by digest + id: build + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + platforms: ${{ matrix.platform }} + outputs: type=image,name=${{ env.IMAGE }},push-by-digest=true,name-canonical=true,push=true + # Attestations turn a single-platform push into a manifest index, which + # breaks push-by-digest + the imagetools merge below. Disable them. + provenance: false + sbom: false + + - name: Export digest + run: | + mkdir -p "${{ runner.temp }}/digests" + digest="${{ steps.build.outputs.digest }}" + touch "${{ runner.temp }}/digests/${digest#sha256:}" + + - name: Upload digest + uses: actions/upload-artifact@v4 + with: + name: digests-${{ env.PLATFORM_PAIR }} + path: ${{ runner.temp }}/digests/* + if-no-files-found: error + retention-days: 1 + + # Combine the per-arch digests into one multi-arch manifest so that + # `docker pull zedeus/nitter:latest` serves the right image on any CPU. + merge: + needs: [build] runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v6 - - name: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@v3 + - name: Download digests + uses: actions/download-artifact@v4 with: - version: latest - - name: Login to DockerHub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - name: Build and push AMD64 Docker image - uses: docker/build-push-action@v3 - with: - context: . - file: ./Dockerfile - platforms: linux/amd64 - push: true - tags: zedeus/nitter:latest,zedeus/nitter:${{ github.sha }} + path: ${{ runner.temp }}/digests + pattern: digests-* + merge-multiple: true - build-docker-arm64: - needs: [tests] - runs-on: ubuntu-24.04-arm - steps: - - uses: actions/checkout@v6 - name: Set up Docker Buildx - id: buildx uses: docker/setup-buildx-action@v3 with: version: latest + - name: Login to DockerHub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - - name: Build and push ARM64 Docker image - uses: docker/build-push-action@v3 - with: - context: . - file: ./Dockerfile - platforms: linux/arm64 - push: true - tags: zedeus/nitter:latest-arm64,zedeus/nitter:${{ github.sha }}-arm64 + + - name: Create manifest list and push + working-directory: ${{ runner.temp }}/digests + run: | + # latest-arm64 is a backward-compat alias of the (now multi-arch) + # latest tag, for users still pinned to the old ARM64-only image. + # word splitting is intentional: one image ref arg per digest file + # shellcheck disable=SC2046 + docker buildx imagetools create \ + -t ${{ env.IMAGE }}:latest \ + -t ${{ env.IMAGE }}:latest-arm64 \ + -t ${{ env.IMAGE }}:${{ github.sha }} \ + $(printf '${{ env.IMAGE }}@sha256:%s ' *) + + - name: Inspect image + run: docker buildx imagetools inspect ${{ env.IMAGE }}:${{ github.sha }} diff --git a/README.md b/README.md index c14cd23..eabd2ac 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ performance reasons. Page for the Docker image: https://hub.docker.com/r/zedeus/nitter -#### NOTE: For ARM64 support, please use the separate ARM64 docker image: [`zedeus/nitter:latest-arm64`](https://hub.docker.com/r/zedeus/nitter/tags). +#### NOTE: The published image is multi-arch — `zedeus/nitter:latest` runs natively on both `amd64` and `arm64`. To run Nitter with Docker, you'll need to install and run Redis separately before you can run the container. See below for how to also run Redis using @@ -147,8 +147,6 @@ docker build -t nitter:latest . docker run -v $(pwd)/nitter.conf:/src/nitter.conf -d --network host nitter:latest ``` -Note: For ARM64, use this Dockerfile: [`Dockerfile.arm64`](https://github.com/zedeus/nitter/blob/master/Dockerfile.arm64). - A prebuilt Docker image is provided as well: ```bash