Dockerfile (renamed from Dockerfile_init, Dockerfile_update removed): - Run as a non-root `builder` user matching the host UID/GID (passed as --build-arg by create() from id -u/id -g), so build output under the bind mount stays owned by the host user instead of root. - Fix CCACHE_MAXSIZE: `ccache -M 5G` wrote its limit to a config file under /ccache at image-build time, but /ccache is a volume mount point, so that file gets shadowed by the (empty) volume the moment the container actually runs - the cap never took effect. Set CCACHE_MAXSIZE=5G as an image ENV instead. - Dedupe ccache/libffi-devel, add --setopt=install_weak_deps=False --setopt=tsflags=nodocs, add `git lfs install --system`, combine the dnf update+install into one layer. - Drop Dockerfile_update: it built FROM its own previous output, so every `update` call made the image strictly larger forever (Docker layers are append-only, `dnf clean` in a later layer can't shrink an earlier one). `update` now just calls create(), which already runs `dnf update -y` FROM a clean rockylinux:9 every time. compose.yaml: pin platform: linux/amd64 so this doesn't silently run under emulation on an ARM host. ifcos_env: - Split the previously-conflated stop/down into six distinct, Compose-native lifecycle commands: up (create-or-start), down (remove), stop, start, restart (stop+start, same container), recreate (down+up, fresh container). Previously `stop` was aliased to `down`, which silently removed the container instead of pausing it. - Implement try(): copies the built wrapper into a real Blender/Bonsai install for manual testing, reading the target from a new BLENDER_USER_RESOURCE .env variable and auto-detecting the built Python version (disambiguating via PY_TGT for multi-version builds). Deliberately kept human-only - it mutates a live Blender install, so it shouldn't run unattended as part of an automated/AI workflow, which should instead copy the wrapper into the repo's own src/ifcopenshell-python/ifcopenshell/ (documented in SKILL.md). - Fix unique(): the "has .env already got a UNIQUE_ID line" check referenced an unset $FILE instead of $ENV_FILE, so it always evaluated true and appended a fresh "UNIQUE_ID=dummy" line to .env on every single `up`. - Minor: differentiate remove()'s log message from down()'s (no longer identical now that they're distinct operations), tidy help text alignment and a stray double-space typo in clean(). SKILL.md: rewritten as current-state documentation (no more "fixed in this copy" changelog framing) covering the above, plus a migration note for anyone hitting root-owned leftovers from an older image. Verified by actually building the image and driving every new lifecycle command (stop/start/restart keep the same container ID; down+up and recreate produce a new one) and try() (including the quoted-tilde BLENDER_USER_RESOURCE edge case) against the real container. Generated with the assistance of an AI coding tool.
Docker build environment
This is a small utility to make it easy to compile a perfect _ifcopenshell_wrapper.cpython-*-x86_64-linux-gnu.so
files.
The reason for this tool is that I was trying to follow the web page directions, and my build was behaving differently
to the release builds. Eventually I concluded that the differences between toolchains on the RHEL based rocky9 image
and Ubuntu were just too great. Getting the build setup was already a lot of trial and error, so I thought I'd spend
more time trying to reuse the github actions that perform the build, using a utility called act. I learnt a lot, in
particular how much time, energy, and bandwidth Github waste. I also realised I was most of the way to a regular docker
setup anyway, so I might as well just do that. So I've deconstructed all the github action steps, and turned it into
a local docker build environment that uses the exact same base, tools, libraries, and build command/flags etc.
Right now a Github action will:
- launch the rocky9 base
- upgrade all the packages
- install a bunch of extra tools
- do a recursive checkout of your repo
- checkout the build repository
- unpack dependencies
- run the build script, making all python versions (5? right now I think)
- create the .zip release files
And it does all of that every time. This is not a fault of the action writers - it's just how Github seems to work.
These dockers tools do the following differently, and it's actually a bit more powerful too:
- build the base image once.
- update the packages once.
- install the extra tools once.
- the repository is the one on your host, that gets bind mounted in the container as the working directory.
- by adding an environment variable to .env, restricts to compiling for just a single python version.
- when the build is finished the created files are right there under your local repositry (but not added to git) for ease of access
- each repository can have it's own build environment container.
- the image is shared between those environments.
- the containers share the ccache, so additional envs should get a helping hand.
- it has a simple set of user friendly commands to drive it all.
For example:
# To see the commands (a superset of docker compose commands)
./ifcos_env
# Enable autocomplete of commands
source .ifcos_env
# First time commands
./ifcos_env create
./ifcos_env up
./ifcos_env build
# install and test library
# find an issue
# edit code
./ifcos_env build
# and so on. When done stop and optionally delete the container
./ifcos_env stop
./ifcos_env remove
To limit the build to one python version just add
PY_TGT=py-311
or whichever version your Blender requires.
You might see UNIQUE_ID in the .env file too. This keeps containers for separate folders, separate.
System requirements
- Linux-x64 only at this time.
- Docker and docker-compose need to be installed.
- Have a good amount of disk space. (image is in /var (typically the root partition) and will be about 1.7 GB)
- The build action will create about 10GB in your repository folder. Make sure this partition is spacious particularly if you intent on having multiple clones building.
- ... I think that covers most of it.