on master help sign in
Assemble rootfs with a host-arch buildEnv so cached sets need no Linux builder
commit39bbc7519dc4030dbe93af795c3c2a417167a180 authoriko <mail@iko.soy> dateSat 27 Jun 2026, 21:48 (3 months ago) parent686fc14
2 files changed+16−9
README.md+12−8 flake.nix+4−1
README.md+12−8
@@ -14,11 +14,12 @@ choose what else it ships via a per-project `container.nix`.
1414- Apple's [`container`](https://github.com/apple/container) CLI installed, with
1515 services started: `container system start` (first run downloads a Linux
1616 kernel).
17−- A **Linux builder** — the image *contents* are Linux binaries, which can't be
18− built on macOS. Use a [remote builder][builders] or, on Apple Silicon, the
19− `nix-darwin` `linux-builder`. With one configured, `nix` dispatches Linux
20− builds to it automatically (most packages also come prebuilt from the binary
21− cache, so the builder is only needed for the uncached bits).
17+- A **Linux builder** *only if you use packages that aren't in the binary
18+ cache*. The image is assembled entirely on macOS — the root filesystem is just
19+ a host-built symlink tree over the **substituted** Linux store paths — so a
20+ fully-cached package set needs no builder. Compiling a Linux package that
21+ `cache.nixos.org` doesn't have does, though: use a [remote builder][builders]
22+ or, on Apple Silicon, the `nix-darwin` `linux-builder`.
2223
2324[builders]: https://nix.dev/manual/nix/latest/advanced-topics/distributed-builds
2425
@@ -106,9 +107,12 @@ system maps to the matching Linux target automatically (an Intel Mac builds an
106107
107108## How it works
108109
109−- **Contents** are built from `pkgsLinux` → the Linux builder.
110−- **Assembly** (`nix2container` + the `skopeo` copy) runs on your Mac, so a
111− single `init` produces a loadable archive.
110+- **Contents** are Linux store paths — downloaded prebuilt from the binary cache
111+ (only built on a Linux builder if not cached).
112+- **Assembly** runs entirely on your Mac: `copyToRoot` is a *host-arch* `buildEnv`
113+ symlink tree over those Linux paths (symlinks are arch-neutral), and
114+ `nix2container` + `skopeo` package it — so for a cached set, `init` produces a
115+ loadable Linux image with no Linux build at all.
112116- Apple's `container` runs each container in its own lightweight Linux VM and
113117 consumes standard OCI images — no `--privileged` or systemd needed.
114118
flake.nix+4−1
@@ -105,7 +105,10 @@
105105 inherit arch;
106106
107107 # A plain, single-process root filesystem. No NixOS, no systemd.
108− copyToRoot = pkgsLinux.buildEnv {
108+ # buildEnv only *symlinks* paths (never runs them), so build it
109+ # on the host arch — the tree is arch-neutral and links the
110+ # (substituted) Linux store paths, sparing the Linux builder.
111+ copyToRoot = pkgsHost.buildEnv {
109112 name = "root";
110113 paths = pkgList;
111114 pathsToLink = [ "/bin" ];