From 44f11eac54ae57e3352ec15131e0b422ef67dd3e Mon Sep 17 00:00:00 2001 From: "Joshua T." Date: Thu, 25 Sep 2025 23:21:45 +0530 Subject: [PATCH] Build and push multi-platform docker image (#1567) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds the `publish-docker-image-multiplatform` CI job step that pushes a multi-platform docker image when a new tag is created. #1211 Unfortunately, this is not as simple as pushing two images targeting different platforms to the same tag. There are a couple of ways to create a multi-platform image: - Using `docker buildx` to build images for all platforms. To do this images targeting non-native platforms would need to be built using QEMU (slower), a remote machine or cross-compilation. - Building and publishing platform-specific images `emscripten/emsdk-x64`, `emscripten/emsdk-arm64` and then creating a manifest that links to these images. This is the simpler solution to implement, and is what this PR does. Tested with CircleCI on my fork. See the pushed images at [radiantly/emsdk ยท DockerHub](https://hub.docker.com/r/radiantly/emsdk/tags) --- .circleci/config.yml | 21 +++++++++++++++++++-- docker/Makefile | 4 ++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f9f1dce..59de9a0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -96,7 +96,6 @@ jobs: python3 -m pip install flake8==7.1.1 python3 -m flake8 --show-source --statistics --extend-exclude=./scripts - test-linux: executor: ubuntu environment: @@ -249,7 +248,7 @@ jobs: name: push image command: | docker login -u "$DOCKER_USER" -p "$DOCKER_PASS" - make -C ./docker version=${CIRCLE_TAG} alias=latest push + make -C ./docker version=${CIRCLE_TAG} alias=${CIRCLE_TAG}-x64 only_alias=true push publish-docker-image-arm64: executor: linux_arm64 @@ -267,6 +266,16 @@ jobs: docker login -u "$DOCKER_USER" -p "$DOCKER_PASS" make -C ./docker version=${CIRCLE_TAG} alias=${CIRCLE_TAG}-arm64 only_alias=true push + publish-docker-image-multiplatform: + executor: linux_arm64 + steps: + - checkout + - run: + name: push image + command: | + docker login -u "$DOCKER_USER" -p "$DOCKER_PASS" + make -C ./docker version=${CIRCLE_TAG} alias="latest" push-multiplatform + test-bazel7-linux: executor: ubuntu environment: @@ -345,6 +354,14 @@ workflows: ignore: /.*/ tags: only: /.*/ + - publish-docker-image-multiplatform: + filters: + tags: + only: /.*/ + requires: + - publish-docker-image-x64 + - publish-docker-image-arm64 + test-bazel7-linux: jobs: - test-bazel7-linux diff --git a/docker/Makefile b/docker/Makefile index 749ecfe..ab28216 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -29,3 +29,7 @@ ifdef alias docker tag ${image_name}:${version} ${image_name}:${alias} docker push ${image_name}:${alias} endif + +push-multiplatform: .TEST + docker manifest create ${image_name}:${version} $(foreach platform,x64 arm64,--amend ${image_name}:${version}-$(platform)) + docker manifest push ${image_name}:${version}