3333# - Handles special case for 'docker' driver (uses default builder)
3434# - Creates or reuses existing builders for other drivers
3535# - Bootstraps builder instances
36- # - Installs binfmt emulation for cross-architecture builds
36+ # - Installs binfmt emulation for cross-architecture builds (now independent of driver)
3737# - Provides summary of available builders
3838#
3939# REQUIREMENTS:
4040# - Docker with Buildx plugin
4141# - Privileged access (for binfmt installation)
4242set -euo pipefail
4343
44-
45-
4644# Config (override via env or args)
4745NAME=" ${1:- ${BUILDX_NAME:- xbuilder} } "
4846DRIVER=" ${DRIVER:- docker} " # docker | docker-container | kubernetes
49- ARCHS=" ${ARCHS:- arm64} " # binfmt architectures to install
47+ ARCHS=" ${ARCHS:- arm64} " # binfmt architectures to install (comma-separated)
5048INSTALL_BINFMT=" ${INSTALL_BINFMT:- 1} "
5149
5250command -v docker > /dev/null || { echo " docker not found" ; exit 1; }
@@ -62,12 +60,12 @@ use_builder () {
6260# Special case: docker driver can only have ONE instance (the implicit 'default')
6361if [[ " $DRIVER " == " docker" ]]; then
6462 echo " [buildx] Using 'docker' driver -> switching to existing 'default' builder"
65- use_builder default || {
63+ if ! use_builder default; then
6664 # On some setups 'default' exists but isn't initialized yet; bootstrap via inspect
6765 docker buildx create --name default --driver docker --use || true
6866 docker buildx inspect default --bootstrap > /dev/null || true
6967 docker buildx use default
70- }
68+ fi
7169else
7270 # For docker-container (recommended) or other drivers: create or reuse NAME
7371 if docker buildx inspect " $NAME " > /dev/null 2>&1 ; then
8482echo " [buildx] Bootstrapping current builder"
8583docker buildx inspect --bootstrap > /dev/null
8684
87- # Install binfmt only when using docker-container (useful for cross-building)
85+ # Snapshot builder/driver for logs
8886CURRENT_BUILDER=" $( docker buildx ls | awk ' /\*/{gsub(/\*/, "", $1); print $1}' ) "
8987CURRENT_DRIVER=" $( docker buildx inspect " $CURRENT_BUILDER " | awk -F' : ' ' /Driver:/ {print $2}' ) "
9088
91- if [[ " $INSTALL_BINFMT " = " 1" && " $CURRENT_DRIVER " = " docker-container" ]]; then
92- echo " [binfmt] Ensuring $ARCHS emulation is installed"
93- docker run --privileged --rm tonistiigi/binfmt --install " $ARCHS " > /dev/null
89+ # --- NEW: Ensure binfmt (QEMU) regardless of driver when requested ---
90+ if [[ " ${INSTALL_BINFMT} " = " 1" ]]; then
91+ # Normalize commas/spaces, split into array
92+ IFS=' ,' read -r -a _ARCHES <<< " $(echo " $ARCHS " | tr -d ' ')"
93+
94+ # Map host arch to docker "platform arch" names for quick decisions
95+ HOST_UNAME=" $( uname -m) "
96+ case " $HOST_UNAME " in
97+ x86_64) HOST_ARCH_DOCKER=" amd64" ;;
98+ aarch64) HOST_ARCH_DOCKER=" arm64" ;;
99+ arm64) HOST_ARCH_DOCKER=" arm64" ;;
100+ * ) HOST_ARCH_DOCKER=" $HOST_UNAME " ;;
101+ esac
102+
103+ echo " [binfmt] Requested arches: ${_ARCHES[*]} (host: $HOST_UNAME -> $HOST_ARCH_DOCKER )"
104+ echo " [binfmt] Ensuring emulators are installed (driver: $CURRENT_DRIVER )"
105+
106+ # Install all requested emulators in one shot (idempotent)
107+ docker run --privileged --rm tonistiigi/binfmt --install " $( IFS=' ,' ; echo " ${_ARCHES[*]} " ) " > /dev/null || {
108+ echo " [binfmt] ERROR: Failed to install binfmt for: ${_ARCHES[*]} " >&2
109+ exit 1
110+ }
111+
112+ # Smoke-test non-native arches using busybox where applicable
113+ # Build map from arch -> platform string
114+ for a in " ${_ARCHES[@]} " ; do
115+ # Skip test for native arch
116+ if [[ " $a " == " $HOST_ARCH_DOCKER " ]]; then
117+ continue
118+ fi
119+ platform=" linux/${a} "
120+ echo " [binfmt] Smoke test for ${platform} ..."
121+ if docker run --rm --platform=" $platform " busybox uname -m 2> /dev/null | grep -qiE ' aarch64|arm64|x86_64|amd64|ppc64le|s390x|riscv64' ; then
122+ echo " [binfmt] OK: ${platform} emulation working"
123+ else
124+ echo " [binfmt] WARNING: ${platform} smoke test did not confirm; emulation may still be fine depending on image availability" >&2
125+ fi
126+ done
127+ else
128+ echo " [binfmt] Skipped (INSTALL_BINFMT=${INSTALL_BINFMT} )"
94129fi
130+ # --------------------------------------------------------------------
95131
96132echo
97133echo " [summary]"
98- docker buildx ls
134+ docker buildx ls
0 commit comments