Skip to content

Commit 64f3142

Browse files
committed
feat: add scripts for native multi-arch Docker image builds and update README with usage instructions
1 parent 9bff4b1 commit 64f3142

File tree

4 files changed

+202
-1
lines changed

4 files changed

+202
-1
lines changed
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
name: Build Multi-Arch Docker Images (Native Runners)
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
docker_dir:
7+
description: 'Docker directory (e.g., runtime-18.15)'
8+
required: true
9+
type: string
10+
image_name:
11+
description: 'Docker image name (e.g., runtime)'
12+
required: true
13+
type: string
14+
tag_prefix:
15+
description: 'Tag prefix (e.g., 18.15.0)'
16+
required: true
17+
type: string
18+
dockerfile:
19+
description: 'Dockerfile name (default: Dockerfile)'
20+
required: false
21+
default: 'Dockerfile'
22+
type: string
23+
24+
jobs:
25+
build:
26+
runs-on: ${{ matrix.runner }}
27+
strategy:
28+
fail-fast: false
29+
matrix:
30+
include:
31+
- platform: linux/amd64
32+
runner: ubuntu-latest
33+
- platform: linux/arm64
34+
runner: ubuntu-latest
35+
steps:
36+
-
37+
name: Prepare
38+
run: |
39+
platform=${{ matrix.platform }}
40+
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
41+
-
42+
name: Checkout
43+
uses: actions/checkout@v4
44+
-
45+
name: Docker meta
46+
id: meta
47+
uses: docker/metadata-action@v5
48+
with:
49+
images: hackmdio/${{ inputs.image_name }}
50+
tags: |
51+
type=raw,value=${{ inputs.tag_prefix }}-{{sha}}
52+
-
53+
name: Set up QEMU
54+
uses: docker/setup-qemu-action@v3
55+
-
56+
name: Set up Docker Buildx
57+
uses: docker/setup-buildx-action@v3
58+
-
59+
name: Login to Docker Hub
60+
uses: docker/login-action@v3
61+
with:
62+
username: ${{ secrets.DOCKERHUB_USERNAME }}
63+
password: ${{ secrets.DOCKERHUB_TOKEN }}
64+
-
65+
name: Build and push by digest
66+
id: build
67+
uses: docker/build-push-action@v5
68+
with:
69+
context: .
70+
file: ./${{ inputs.docker_dir }}/${{ inputs.dockerfile }}
71+
platforms: ${{ matrix.platform }}
72+
labels: ${{ steps.meta.outputs.labels }}
73+
outputs: type=image,name=hackmdio/${{ inputs.image_name }},push-by-digest=true,name-canonical=true,push=true
74+
-
75+
name: Export digest
76+
run: |
77+
mkdir -p /tmp/digests
78+
digest="${{ steps.build.outputs.digest }}"
79+
touch "/tmp/digests/${digest#sha256:}"
80+
-
81+
name: Upload digest
82+
uses: actions/upload-artifact@v4
83+
with:
84+
name: digests-${{ env.PLATFORM_PAIR }}
85+
path: /tmp/digests/*
86+
if-no-files-found: error
87+
retention-days: 1
88+
89+
merge:
90+
runs-on: ubuntu-latest
91+
needs:
92+
- build
93+
steps:
94+
-
95+
name: Download digests
96+
uses: actions/download-artifact@v4
97+
with:
98+
path: /tmp/digests
99+
pattern: digests-*
100+
merge-multiple: true
101+
-
102+
name: Set up Docker Buildx
103+
uses: docker/setup-buildx-action@v3
104+
-
105+
name: Docker meta
106+
id: meta
107+
uses: docker/metadata-action@v5
108+
with:
109+
images: hackmdio/${{ inputs.image_name }}
110+
tags: |
111+
type=raw,value=${{ inputs.tag_prefix }}-{{sha}}
112+
-
113+
name: Login to Docker Hub
114+
uses: docker/login-action@v3
115+
with:
116+
username: ${{ secrets.DOCKERHUB_USERNAME }}
117+
password: ${{ secrets.DOCKERHUB_TOKEN }}
118+
-
119+
name: Create manifest list and push
120+
working-directory: /tmp/digests
121+
run: |
122+
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
123+
$(printf 'hackmdio/${{ inputs.image_name }}@sha256:%s ' *)
124+
-
125+
name: Inspect image
126+
run: |
127+
docker buildx imagetools inspect hackmdio/${{ inputs.image_name }}:${{ steps.meta.outputs.version }}

README.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,34 @@
11
## How to build docker image for multi-arch
22

3-
```
3+
### Using Docker Buildx (Cross-platform emulation)
4+
5+
```bash
46
./build-multi-arch.sh runtime-16 runtime 16.20.2
57
./build-multi-arch.sh runtime-18.15 runtime 18.15.0
68
./build-multi-arch.sh buildpack-18.15 buildpack 18.15.0
79
```
10+
11+
### Using GitHub Actions Workflow
12+
13+
Use the "Build Multi-Arch Docker Images (Native Runners)" workflow in GitHub Actions with workflow_dispatch trigger. This uses a digest-based approach for robust multi-arch builds.
14+
15+
Example parameters:
16+
- `docker_dir`: `runtime-18.15`
17+
- `image_name`: `runtime`
18+
- `tag_prefix`: `18.15.0`
19+
- `dockerfile`: `Dockerfile` (optional)
20+
21+
**Prerequisites**: Set up `DOCKERHUB_USERNAME` and `DOCKERHUB_TOKEN` secrets in your GitHub repository.
22+
23+
**Note**: The workflow currently uses QEMU emulation on ubuntu-latest runners. For true native builds, change the ARM64 runner to `ubuntu-latest-arm64` if available in your GitHub account.
24+
25+
### Manual Native Build Process
26+
27+
```bash
28+
# Build for each platform natively
29+
./build-native.sh runtime-18.15 runtime 18.15.0 linux/amd64
30+
./build-native.sh runtime-18.15 runtime 18.15.0 linux/arm64
31+
32+
# Create multi-arch manifest
33+
./create-manifest.sh runtime 18.15.0
34+
```

build-native.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
DOCKER_DIR="$1"
6+
DOCKER_IMAGE_NAME="$2"
7+
DOCKER_IMAGE_TAG_PREFIX="$3"
8+
PLATFORM="$4"
9+
DOCKER_FILE="${5:-Dockerfile}"
10+
11+
SHA1="$(git rev-parse HEAD)"
12+
SHORT_ID="${SHA1:0:8}"
13+
14+
# Convert platform format (linux/amd64 -> amd64, linux/arm64 -> arm64)
15+
ARCH=$(echo "$PLATFORM" | cut -d'/' -f2)
16+
17+
# Build and push platform-specific image
18+
PLATFORM_TAG="hackmdio/$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG_PREFIX-$SHORT_ID-$ARCH"
19+
echo "Building $PLATFORM_TAG for platform $PLATFORM"
20+
21+
docker build --platform "$PLATFORM" --tag "$PLATFORM_TAG" -f "./$DOCKER_DIR/$DOCKER_FILE" .
22+
docker push "$PLATFORM_TAG"
23+
24+
echo "Successfully built and pushed $PLATFORM_TAG"

create-manifest.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
DOCKER_IMAGE_NAME="$1"
6+
DOCKER_IMAGE_TAG_PREFIX="$2"
7+
8+
SHA1="$(git rev-parse HEAD)"
9+
SHORT_ID="${SHA1:0:8}"
10+
11+
MANIFEST_TAG="hackmdio/$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG_PREFIX-$SHORT_ID"
12+
AMD64_TAG="hackmdio/$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG_PREFIX-$SHORT_ID-amd64"
13+
ARM64_TAG="hackmdio/$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG_PREFIX-$SHORT_ID-arm64"
14+
15+
echo "Creating multi-arch manifest $MANIFEST_TAG"
16+
17+
# Create and push multi-arch manifest
18+
docker manifest create "$MANIFEST_TAG" "$AMD64_TAG" "$ARM64_TAG"
19+
docker manifest annotate "$MANIFEST_TAG" "$AMD64_TAG" --arch amd64
20+
docker manifest annotate "$MANIFEST_TAG" "$ARM64_TAG" --arch arm64
21+
docker manifest push "$MANIFEST_TAG"
22+
23+
echo "Successfully created and pushed multi-arch manifest $MANIFEST_TAG"

0 commit comments

Comments
 (0)