Skip to content

Commit 3759ac9

Browse files
authored
Multi-platform Docker build using native runners (#1182)
1 parent 0294609 commit 3759ac9

File tree

3 files changed

+83
-52
lines changed

3 files changed

+83
-52
lines changed
Lines changed: 72 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# Multi-platform Docker build using native runners
2+
# Reference: https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners
13
name: Weaver Docker Generator
24
on:
35
push:
@@ -11,10 +13,19 @@ permissions:
1113
contents: read
1214
env:
1315
TEST_WEAVER_TAG: otel/weaver:test
16+
REGISTRY_IMAGE: otel/weaver
1417
jobs:
15-
make-docker-image:
16-
name: Docker Image
17-
runs-on: ubuntu-latest
18+
build:
19+
name: Build ${{ matrix.platform }}
20+
runs-on: ${{ matrix.runner }}
21+
strategy:
22+
fail-fast: false
23+
matrix:
24+
include:
25+
- platform: linux/amd64
26+
runner: ubuntu-latest
27+
- platform: linux/arm64
28+
runner: ubuntu-24.04-arm
1829
steps:
1930
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
2031
- name: Setup Node.js
@@ -23,38 +34,84 @@ jobs:
2334
node-version-file: '.nvmrc'
2435
cache: 'npm'
2536
cache-dependency-path: ui/package-lock.json
26-
- name: Set up QEMU
27-
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
2837
- name: Set up Docker Buildx
2938
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
3039
- name: Extract metadata (tags, labels) for Docker
3140
id: meta
3241
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
3342
with:
34-
images: otel/weaver
43+
images: ${{ env.REGISTRY_IMAGE }}
3544
- name: Build test image
3645
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
3746
with:
38-
push: false
39-
load: true
40-
tags: ${{ env.TEST_WEAVER_TAG }}
41-
labels: ${{ steps.meta.outputs.labels }}
47+
push: false
48+
load: true
49+
platforms: ${{ matrix.platform }}
50+
tags: ${{ env.TEST_WEAVER_TAG }}
51+
labels: ${{ steps.meta.outputs.labels }}
4252
- name: Test
4353
run: |
44-
docker run --rm ${{ env.TEST_WEAVER_TAG }} --help
54+
docker run --rm ${{ env.TEST_WEAVER_TAG }} --help
4555
- name: Log in to Docker Hub
4656
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
4757
if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')
4858
with:
4959
username: ${{ secrets.DOCKER_USERNAME }}
5060
password: ${{ secrets.DOCKER_PASSWORD }}
51-
- name: Build and push
61+
- name: Build and push by digest
62+
id: build
5263
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
5364
if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')
5465
with:
55-
push: true
56-
platforms: linux/amd64,linux/arm64
66+
platforms: ${{ matrix.platform }}
5767
provenance: mode=max
5868
sbom: true
59-
tags: ${{ steps.meta.outputs.tags }}
6069
labels: ${{ steps.meta.outputs.labels }}
70+
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
71+
- name: Export digest
72+
if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')
73+
run: |
74+
mkdir -p /tmp/digests
75+
digest="${{ steps.build.outputs.digest }}"
76+
touch "/tmp/digests/${digest#sha256:}"
77+
- name: Upload digest
78+
if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')
79+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
80+
with:
81+
name: digests-${{ matrix.platform == 'linux/amd64' && 'amd64' || 'arm64' }}
82+
path: /tmp/digests/*
83+
if-no-files-found: error
84+
retention-days: 1
85+
86+
merge:
87+
name: Merge manifests
88+
runs-on: ubuntu-latest
89+
if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')
90+
needs: build
91+
steps:
92+
- name: Download digests
93+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
94+
with:
95+
path: /tmp/digests
96+
pattern: digests-*
97+
merge-multiple: true
98+
- name: Set up Docker Buildx
99+
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
100+
- name: Extract metadata (tags, labels) for Docker
101+
id: meta
102+
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
103+
with:
104+
images: ${{ env.REGISTRY_IMAGE }}
105+
- name: Log in to Docker Hub
106+
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
107+
with:
108+
username: ${{ secrets.DOCKER_USERNAME }}
109+
password: ${{ secrets.DOCKER_PASSWORD }}
110+
- name: Create manifest list and push
111+
working-directory: /tmp/digests
112+
run: |
113+
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
114+
$(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
115+
- name: Inspect image
116+
run: |
117+
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }}

Dockerfile

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
# The build image
2-
FROM --platform=$BUILDPLATFORM docker.io/rust:1.93.0@sha256:4c7eb947d7e078f5c076e086c7b75c36ea0ec7c685f2244b3d79306deb7e44b7 AS weaver-build
2+
FROM docker.io/rust:1.93.0@sha256:4c7eb947d7e078f5c076e086c7b75c36ea0ec7c685f2244b3d79306deb7e44b7 AS weaver-build
33
WORKDIR /build
4-
ARG BUILDPLATFORM
5-
ARG TARGETPLATFORM
64

75
# Install Node.js and musl build dependencies
86
# renovate: datasource=node-version depName=node
97
ARG NODE_VERSION=24
108
RUN curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION}.x | bash - && \
11-
apt-get install -y nodejs musl-tools musl-dev perl wget
9+
apt-get install -y nodejs musl-tools musl-dev perl
1210

1311
# Copy UI package files first for better layer caching
1412
COPY ui/package.json ui/package-lock.json /build/ui/

cross-arch-build.sh

Lines changed: 9 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,23 @@
11
#!/bin/sh
22
set -exu
33

4-
# Detect actual host architecture (not Docker platform vars which may differ with QEMU)
4+
# Detect host architecture for native musl builds
55
HOST_ARCH=$(uname -m)
66
echo "Host architecture: ${HOST_ARCH}"
7-
echo "Build platform: ${BUILDPLATFORM}"
8-
echo "Target platform: ${TARGETPLATFORM}"
97

10-
case "${TARGETPLATFORM}" in
11-
linux/amd64)
8+
case "${HOST_ARCH}" in
9+
x86_64)
1210
RUST_TARGET=x86_64-unknown-linux-musl
13-
if [ "${HOST_ARCH}" = "x86_64" ]; then
14-
# Native x86_64 - musl-tools provides musl-gcc
15-
export CC_x86_64_unknown_linux_musl=musl-gcc
16-
export CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER=musl-gcc
17-
else
18-
# Cross-compiling to x86_64 from another arch
19-
wget -q https://musl.cc/x86_64-linux-musl-cross.tgz
20-
echo "52abd1a56e670952116e35d1a62e048a9b6160471d988e16fa0e1611923dd108a581d2e00874af5eb04e4968b1ba32e0eb449a1f15c3e4d5240ebe09caf5a9f3 x86_64-linux-musl-cross.tgz" | sha512sum -c -
21-
tar xf x86_64-linux-musl-cross.tgz -C /opt
22-
export PATH="/opt/x86_64-linux-musl-cross/bin:$PATH"
23-
export CC_x86_64_unknown_linux_musl=x86_64-linux-musl-gcc
24-
export CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER=x86_64-linux-musl-gcc
25-
fi
11+
export CC_x86_64_unknown_linux_musl=musl-gcc
12+
export CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER=musl-gcc
2613
;;
27-
linux/arm64*)
14+
aarch64)
2815
RUST_TARGET=aarch64-unknown-linux-musl
29-
if [ "${HOST_ARCH}" = "aarch64" ]; then
30-
# Native arm64 - musl-tools provides musl-gcc
31-
export CC_aarch64_unknown_linux_musl=musl-gcc
32-
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER=musl-gcc
33-
else
34-
# Cross-compiling to arm64 from x86_64
35-
wget -q https://musl.cc/aarch64-linux-musl-cross.tgz
36-
echo "8695ff86979cdf30fbbcd33061711f5b1ebc3c48a87822b9ca56cde6d3a22abd4dab30fdcd1789ac27c6febbaeb9e5bde59d79d66552fae53d54cc1377a19272 aarch64-linux-musl-cross.tgz" | sha512sum -c -
37-
tar xf aarch64-linux-musl-cross.tgz -C /opt
38-
export PATH="/opt/aarch64-linux-musl-cross/bin:$PATH"
39-
export CC_aarch64_unknown_linux_musl=aarch64-linux-musl-gcc
40-
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER=aarch64-linux-musl-gcc
41-
fi
16+
export CC_aarch64_unknown_linux_musl=musl-gcc
17+
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER=musl-gcc
4218
;;
4319
*)
44-
echo "Unsupported target platform: ${TARGETPLATFORM}"
20+
echo "Unsupported architecture: ${HOST_ARCH}"
4521
exit 1
4622
;;
4723
esac

0 commit comments

Comments
 (0)