feat: add ARM64/aarch64 multi-arch Docker image support

Build amd64 and arm64 images in parallel on native GitHub runners
(ubuntu-24.04 and ubuntu-24.04-arm) then combine them into a single
multi-arch manifest. This enables running on Raspberry Pi and other
ARM devices.

Closes #416
This commit is contained in:
Dylan M. Taylor 2026-03-20 09:49:02 -04:00
parent ed0b0f76ec
commit 713b09a8c2
No known key found for this signature in database
GPG Key ID: EC2AAF6D2213BF17
3 changed files with 147 additions and 18 deletions

View File

@ -13,6 +13,9 @@ on:
type: boolean
default: false
env:
IMAGE: ghcr.io/crosstalk-solutions/project-nomad-disk-collector
jobs:
check_authorization:
name: Check authorization to publish new Docker image
@ -23,29 +26,69 @@ jobs:
- name: check-auth
id: check-auth
run: echo "is_authorized=${{ contains(secrets.DEPLOYMENT_AUTHORIZED_USERS, github.triggering_actor) }}" >> $GITHUB_OUTPUT
build:
name: Build disk-collector image
name: Build Docker image (${{ matrix.platform }})
needs: check_authorization
if: needs.check_authorization.outputs.isAuthorized == 'true'
runs-on: ubuntu-latest
runs-on: ${{ matrix.runner }}
permissions:
contents: read
packages: write
strategy:
matrix:
include:
- platform: linux/amd64
runner: ubuntu-24.04
suffix: amd64
- platform: linux/arm64
runner: ubuntu-24.04-arm
suffix: arm64
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: install/sidecar-disk-collector
push: true
tags: |
ghcr.io/crosstalk-solutions/project-nomad-disk-collector:${{ inputs.version }}
ghcr.io/crosstalk-solutions/project-nomad-disk-collector:v${{ inputs.version }}
${{ inputs.tag_latest && 'ghcr.io/crosstalk-solutions/project-nomad-disk-collector:latest' || '' }}
platforms: ${{ matrix.platform }}
tags: ${{ env.IMAGE }}:${{ inputs.version }}-${{ matrix.suffix }}
manifest:
name: Create multi-arch manifest
needs: build
runs-on: ubuntu-latest
permissions:
packages: write
steps:
- name: Log in to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create and push manifest
run: |
TAGS="${{ env.IMAGE }}:${{ inputs.version }} ${{ env.IMAGE }}:v${{ inputs.version }}"
if [ "${{ inputs.tag_latest }}" = "true" ]; then
TAGS="$TAGS ${{ env.IMAGE }}:latest"
fi
for TAG in $TAGS; do
docker manifest create "$TAG" \
"${{ env.IMAGE }}:${{ inputs.version }}-amd64" \
"${{ env.IMAGE }}:${{ inputs.version }}-arm64"
docker manifest push "$TAG"
done

View File

@ -13,6 +13,9 @@ on:
type: boolean
default: false
env:
IMAGE: ghcr.io/crosstalk-solutions/project-nomad
jobs:
check_authorization:
name: Check authorization to publish new Docker image
@ -23,32 +26,72 @@ jobs:
- name: check-auth
id: check-auth
run: echo "is_authorized=${{ contains(secrets.DEPLOYMENT_AUTHORIZED_USERS, github.triggering_actor) }}" >> $GITHUB_OUTPUT
build:
name: Build Docker image
name: Build Docker image (${{ matrix.platform }})
needs: check_authorization
if: needs.check_authorization.outputs.isAuthorized == 'true'
runs-on: ubuntu-latest
runs-on: ${{ matrix.runner }}
permissions:
contents: read
packages: write
strategy:
matrix:
include:
- platform: linux/amd64
runner: ubuntu-24.04
suffix: amd64
- platform: linux/arm64
runner: ubuntu-24.04-arm
suffix: arm64
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
push: true
tags: |
ghcr.io/crosstalk-solutions/project-nomad:${{ inputs.version }}
ghcr.io/crosstalk-solutions/project-nomad:v${{ inputs.version }}
${{ inputs.tag_latest && 'ghcr.io/crosstalk-solutions/project-nomad:latest' || '' }}
platforms: ${{ matrix.platform }}
tags: ${{ env.IMAGE }}:${{ inputs.version }}-${{ matrix.suffix }}
build-args: |
VERSION=${{ inputs.version }}
BUILD_DATE=${{ github.event.workflow_run.created_at }}
VCS_REF=${{ github.sha }}
manifest:
name: Create multi-arch manifest
needs: build
runs-on: ubuntu-latest
permissions:
packages: write
steps:
- name: Log in to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create and push manifest
run: |
TAGS="${{ env.IMAGE }}:${{ inputs.version }} ${{ env.IMAGE }}:v${{ inputs.version }}"
if [ "${{ inputs.tag_latest }}" = "true" ]; then
TAGS="$TAGS ${{ env.IMAGE }}:latest"
fi
for TAG in $TAGS; do
docker manifest create "$TAG" \
"${{ env.IMAGE }}:${{ inputs.version }}-amd64" \
"${{ env.IMAGE }}:${{ inputs.version }}-arm64"
docker manifest push "$TAG"
done

View File

@ -13,6 +13,9 @@ on:
type: boolean
default: false
env:
IMAGE: ghcr.io/crosstalk-solutions/project-nomad-sidecar-updater
jobs:
check_authorization:
name: Check authorization to publish new Docker image
@ -23,29 +26,69 @@ jobs:
- name: check-auth
id: check-auth
run: echo "is_authorized=${{ contains(secrets.DEPLOYMENT_AUTHORIZED_USERS, github.triggering_actor) }}" >> $GITHUB_OUTPUT
build:
name: Build sidecar-updater image
name: Build Docker image (${{ matrix.platform }})
needs: check_authorization
if: needs.check_authorization.outputs.isAuthorized == 'true'
runs-on: ubuntu-latest
runs-on: ${{ matrix.runner }}
permissions:
contents: read
packages: write
strategy:
matrix:
include:
- platform: linux/amd64
runner: ubuntu-24.04
suffix: amd64
- platform: linux/arm64
runner: ubuntu-24.04-arm
suffix: arm64
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: install/sidecar-updater
push: true
tags: |
ghcr.io/crosstalk-solutions/project-nomad-sidecar-updater:${{ inputs.version }}
ghcr.io/crosstalk-solutions/project-nomad-sidecar-updater:v${{ inputs.version }}
${{ inputs.tag_latest && 'ghcr.io/crosstalk-solutions/project-nomad-sidecar-updater:latest' || '' }}
platforms: ${{ matrix.platform }}
tags: ${{ env.IMAGE }}:${{ inputs.version }}-${{ matrix.suffix }}
manifest:
name: Create multi-arch manifest
needs: build
runs-on: ubuntu-latest
permissions:
packages: write
steps:
- name: Log in to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create and push manifest
run: |
TAGS="${{ env.IMAGE }}:${{ inputs.version }} ${{ env.IMAGE }}:v${{ inputs.version }}"
if [ "${{ inputs.tag_latest }}" = "true" ]; then
TAGS="$TAGS ${{ env.IMAGE }}:latest"
fi
for TAG in $TAGS; do
docker manifest create "$TAG" \
"${{ env.IMAGE }}:${{ inputs.version }}-amd64" \
"${{ env.IMAGE }}:${{ inputs.version }}-arm64"
docker manifest push "$TAG"
done