Skip to content

feat: macOS sandbox support via Docker-based Nix builder#4

Merged
HashWarlock merged 13 commits intomasterfrom
macos-docker-builder
Apr 10, 2026
Merged

feat: macOS sandbox support via Docker-based Nix builder#4
HashWarlock merged 13 commits intomasterfrom
macos-docker-builder

Conversation

@HashWarlock
Copy link
Copy Markdown
Owner

@HashWarlock HashWarlock commented Apr 10, 2026

Summary

  • Docker-based build path for macOS: nix build runs inside a nixos/nix container (linux/amd64 via Rosetta) with a persistent Docker volume (nixosandbox-nix) for incremental builds
  • Shared volume architecture: builder writes to the volume, sidecar reads from it — no store export/import needed
  • E2E CI tests for both platforms: Linux (native bwrap, isolation=native) and macOS (Docker builder + sidecar, isolation=docker)

What was broken

On macOS (aarch64-darwin), nixosandbox create failed with:

error: a 'x86_64-linux' with features {} is required to build '...builder.pl.drv',
but I am a 'aarch64-darwin'

The execution side (bwrap) had Docker sidecar support, but the build side had no macOS path.

Changes

File Change
docker/nixosandbox-builder.Dockerfile New — nixos/nix image with numtide cache + flakes
crates/nixosandbox/src/docker.rs Builder image mgmt, nix_build_in_docker(), sidecar uses shared volume
crates/nixosandbox/src/nix.rs Non-Linux delegation to Docker, --accept-flake-config on all builds
.github/workflows/ci.yml Linux E2E + macOS E2E jobs

Test plan

  • cargo test — 20/20 pass
  • Local macOS: create --profile strict via Docker builder
  • Local macOS: create --with openclaw,bash,cacert,coreutils via Docker builder
  • Local macOS: exec <id> -- echo "Hello" via Docker sidecar
  • CI: Linux E2E (create → exec → status → destroy)
  • CI: macOS E2E (catalog → create → exec → status → destroy)

🤖 Generated with Claude Code

HashWarlock and others added 13 commits April 10, 2026 10:02
On macOS, `nix build` cannot produce x86_64-linux derivations locally.
This adds a Docker-based build path that runs `nix build` inside a
`nixos/nix` container (linux/amd64 via Rosetta), with a persistent
Docker volume for the Nix store so builds are incremental.

- docker.rs: add builder image management, `nix_build_in_docker()` and
  `nix_build_expr_in_docker()`; sidecar now mounts shared
  `nixosandbox-nix` volume instead of host `/nix/store`
- nix.rs: `build_profile`, `build_spec`, `build_with_catalog` delegate
  to Docker on non-Linux; `validate_rootfs` checks path format on macOS;
  `--accept-flake-config` added to all nix build invocations
- ci.yml: add Linux E2E test (create → exec → destroy with isolation
  assertion) and macOS E2E test (Docker builder + sidecar)
- New `docker/nixosandbox-builder.Dockerfile` with numtide cache config

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
docker/setup-docker-action uses Lima which crashes on GitHub's macOS
runners (QEMU abort trap). Colima is more stable for CI environments.
Uses --arch x86_64 to match the linux/amd64 builder requirement.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Lima 2.1.1 on ARM macOS lacks the x86_64 guest agent by default,
causing `colima start --arch x86_64` to fail. The --arch flag is
unnecessary: our Rust code already passes `--platform linux/amd64`
to all Docker commands, which Docker handles via QEMU emulation
inside the native arm64 VM.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@HashWarlock HashWarlock changed the base branch from pi-sandbox-refactor to master April 10, 2026 17:48
@HashWarlock HashWarlock merged commit b180a10 into master Apr 10, 2026
14 checks passed
@HashWarlock HashWarlock deleted the macos-docker-builder branch April 11, 2026 01:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant