docker: make the build env work on macOS / Apple Silicon hosts

Three host-portability fixes to the docker/ toolchain from #8564 so it
runs on macOS as well as Linux. All three are no-ops on native amd64
Linux.

1. Dockerfile: only groupadd when the target GID is free. macOS's default
   primary group `staff` is GID 20, which already exists as `games` in
   rockylinux:9, so `groupadd -g 20` aborted the image build. Guard with
   `getent group "${USER_GID}" || groupadd ...`; useradd -g accepts the
   existing GID.

2. ifcos_env unique(): replace GNU-only `sed -si` (BSD/macOS sed errors
   "illegal option -- s") with a portable `sed > tmp && mv` rewrite of the
   UNIQUE_ID line. Verified against macOS BSD sed.

3. create() + compose.yaml: build with an explicit `--platform linux/amd64`
   so the locally built image's platform matches the `platform:
   linux/amd64` pin in compose.yaml. Without it, on arm64 the local image
   is tagged linux/arm64, compose treats the platform-mismatched image as
   absent and tries to pull `ifcopenshell-build-env:updated` from Docker
   Hub (which does not exist -> access denied). Also add `pull_policy:
   never` as a safety net so a future mismatch surfaces as a clear "image
   not found" rather than a registry auth error.

Note: on Apple Silicon the amd64 build runs under emulation and a cold
full build is slow; ccache makes incremental rebuilds tolerable. A native
Linux/Intel host or CI remains the better choice for routine use, but these
fixes turn "hard broken" into "works with a caveat" on macOS.

This change was made with the assistance of an AI tool.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Petru Conduraru
2026-07-13 06:44:55 +03:00
parent ffb867f254
commit f25b072fa0
3 changed files with 38 additions and 2 deletions
+21 -1
View File
@@ -24,7 +24,18 @@ set_env
function create() {
echo "⭐ Creating image: ifcopenshell-build-env"
# compose.yaml pins the service to platform: linux/amd64 (this stack
# always targets the rockylinux9-x64 build-outputs branch and produces
# linux64 artifacts, regardless of host arch). Building without
# --platform would tag the image for the host's native arch instead -
# harmless on an amd64 host, but on an arm64 host (e.g. Apple Silicon)
# it leaves a local image that doesn't match what compose asked for, so
# `docker compose up` decides the requested platform is "missing" and
# tries to pull ifcopenshell-build-env:updated from Docker Hub instead
# of using the image just built. Pinning the build platform here keeps
# the local image's arch in sync with compose's pin on every host.
docker build -f Dockerfile \
--platform linux/amd64 \
--build-arg USER_UID="$(id -u)" --build-arg USER_GID="$(id -g)" \
-t ifcopenshell-build-env:updated .
}
@@ -112,7 +123,16 @@ function unique() {
echo -e "\nUNIQUE_ID=dummy\n" >> "$ENV_FILE"
fi
export UNIQUE_ID="$(pwd | sha256sum | cut -c -8)" && sed -si "s/^UNIQUE_ID=.*$/UNIQUE_ID=${UNIQUE_ID}/" "$ENV_FILE"
export UNIQUE_ID="$(pwd | sha256sum | cut -c -8)"
# `sed -i` takes incompatible syntax between GNU sed (Linux) and BSD sed
# (macOS) - `-si` is GNU-only and errors as "illegal option -- s" under
# BSD/macOS sed. Avoid -i altogether and do the in-place edit via a temp
# file + mv instead, which behaves identically with either sed.
local tmp_file
tmp_file="$(mktemp "${ENV_FILE}.XXXXXX")"
sed "s/^UNIQUE_ID=.*$/UNIQUE_ID=${UNIQUE_ID}/" "$ENV_FILE" > "$tmp_file"
mv "$tmp_file" "$ENV_FILE"
set_env
}