mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-05 23:41:44 +00:00
4f0e1f718d
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)
65 lines
3.2 KiB
Docker
65 lines
3.2 KiB
Docker
FROM rockylinux:9
|
|
|
|
# Update system, enable CRB (needed by some EPEL packages) and install EPEL,
|
|
# then install required packages + some common tools for a bit of command
|
|
# line comfort. Combined into one layer so a later `create` always installs
|
|
# against packages from the same dnf update, rather than layering fresh
|
|
# installs on top of a stale cached "update" layer.
|
|
RUN dnf update -y && \
|
|
dnf install -y epel-release && \
|
|
dnf config-manager --set-enabled crb && \
|
|
dnf install -y --allowerasing --setopt=install_weak_deps=False --setopt=tsflags=nodocs \
|
|
bash-completion vim git curl wget which tree htop sudo \
|
|
gcc gcc-c++ autoconf automake bison make zip cmake \
|
|
python3 python3-pip \
|
|
bzip2 patch mesa-libGL-devel libffi-devel fontconfig-devel \
|
|
sqlite-devel bzip2-devel zlib-devel openssl-devel xz-devel \
|
|
readline-devel ncurses-devel libuuid-devel git-lfs \
|
|
findutils xz byacc ccache && \
|
|
git lfs install --system && \
|
|
dnf clean all && \
|
|
rm -rf /var/cache/dnf
|
|
|
|
# Trust bind-mounted repos regardless of which user (root or builder) or host
|
|
# UID owns them, rather than a per-user config that only one of them sees.
|
|
RUN git config --system --add safe.directory '*'
|
|
|
|
# Configure ccache. CCACHE_MAXSIZE (not `ccache -M`) because /ccache is a
|
|
# volume mount point at runtime - anything `ccache -M` writes to a config
|
|
# file under it during this build gets shadowed once the real volume is
|
|
# mounted, so the size cap only actually takes effect via the env var.
|
|
ENV CCACHE_DIR=/ccache
|
|
ENV CCACHE_MAXSIZE=5G
|
|
ENV PATH="/usr/lib/ccache:$PATH"
|
|
|
|
# Non-root user matching the host UID/GID that bind-mounts the repo (default
|
|
# 1000:1000, the common single-user-Linux-box case), so files the build
|
|
# creates under the mount keep sane, non-root ownership on the host side.
|
|
# Override with --build-arg USER_UID=$(id -u) --build-arg USER_GID=$(id -g)
|
|
# if your host user has a different UID/GID.
|
|
ARG USER_UID=1000
|
|
ARG USER_GID=1000
|
|
# 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
|
|
|
|
# Copied while still root: /bin is not writable by the builder user.
|
|
COPY --from=ghcr.io/astral-sh/uv:0.11.27 /uv /uvx /bin/
|
|
|
|
USER builder
|
|
WORKDIR /__w/IfcOpenShell/IfcOpenShell
|
|
|
|
# Installed as builder so managed Python interpreters land under builder's
|
|
# $HOME, matching the user that actually runs the build.
|
|
RUN uv python install
|
|
|
|
CMD ["sleep", "infinity"]
|