mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-05 23:41:44 +00:00
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>
(cherry picked from commit f25b072fa0)
This commit is contained in:
committed by
Dion Moult
parent
0ee1bc7547
commit
4f0e1f718d
+9
-1
@@ -39,7 +39,15 @@ ENV PATH="/usr/lib/ccache:$PATH"
|
||||
# if your host user has a different UID/GID.
|
||||
ARG USER_UID=1000
|
||||
ARG USER_GID=1000
|
||||
RUN groupadd -g "${USER_GID}" builder \
|
||||
# groupadd fails outright if USER_GID is already taken by an existing
|
||||
# system group - which happens whenever a host's primary GID collides with
|
||||
# one baked into the rockylinux9 base image. The main real-world case is
|
||||
# macOS, where the default user's primary group is "staff" at GID 20, and
|
||||
# GID 20 is "games" on RHEL-family images. Only create the "builder" group
|
||||
# when that GID is actually free; otherwise useradd just attaches to
|
||||
# whichever group already owns it. Either way the builder user ends up
|
||||
# with the right GID for bind-mount ownership, which is all that matters.
|
||||
RUN (getent group "${USER_GID}" >/dev/null || groupadd -g "${USER_GID}" builder) \
|
||||
&& useradd -m -u "${USER_UID}" -g "${USER_GID}" -s /bin/bash builder \
|
||||
&& echo "builder ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/builder
|
||||
|
||||
|
||||
@@ -4,6 +4,14 @@ services:
|
||||
container_name: ifcopenshell-${UNIQUE_ID}
|
||||
image: ifcopenshell-build-env:updated
|
||||
platform: linux/amd64
|
||||
# There's no `build:` section - the image is always produced ahead of
|
||||
# time by `./ifcos_env create` (`docker build`, not `docker compose
|
||||
# build`). Without this, a platform mismatch between the pin above and
|
||||
# whatever's in the local image store makes compose treat the image as
|
||||
# absent and fall back to pulling ifcopenshell-build-env:updated from
|
||||
# Docker Hub, where it doesn't exist. Fail fast with a clear "not
|
||||
# found" instead of an obscure registry access-denied error.
|
||||
pull_policy: never
|
||||
volumes:
|
||||
- type: bind
|
||||
source: ../
|
||||
|
||||
+21
-1
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user