-
Notifications
You must be signed in to change notification settings - Fork 1
Build Environment
This covers the unified build container (ghcr.io/coreflake1/nebulaos-build) — why it exists,
what's actually in it, what deliberately isn't, and what has to pass before a new version of it
becomes the one everyone builds against.
Every host-level build tool the 00–06 build stages invoke — gcc/g++, make, cmake, python3, git,
the autotools family, dtc, mksquashfs, e2fsprogs, and so on — baked into the image at build
time instead of apt-get install'd mid-build. It also bundles GuppyScreen's exact Bootlin
mips32el-musl cross-toolchain, kept on a non-default PATH entry (GUPPYSCREEN_TOOLCHAIN_BIN)
rather than the image's global PATH — its bundled autoreconf would otherwise shadow the system
one a v4l2-ctl build needs, a real bug we found and fixed while putting this together.
See build-env/Dockerfile and build-env/versions.env in the repo for the exact, current,
authoritative list.
-
Project source.
NebulaOS-firmware,NebulaOS-kernel,NebulaOS-klipper,NebulaOS-guppyscreen, Buildroot, Moonraker, kernel source — all fetched fresh by00-fetch-vendor-sources.shat build time, pinned inmanifests/dependencies.conf. Think of the image as the factory and the manifest as the material list. -
The kernel/rootfs/native-app target compiler.
mipsel-buildroot-linux-gnu-*is Buildroot's own self-bootstrapped toolchain, built from source during Stage 03 from the project's pinned Buildroot revision. Bundling a pre-built copy would defeat the whole point of pinning Buildroot — this image only supplies the host compiler Buildroot itself needs to build it.
A floating tag (:latest, :candidate) can get silently repointed at different content later —
we actually closed exactly this gap once already for pellcorp/k1-bash-build, the container this
one replaced. A digest is content-addressed: ghcr.io/coreflake1/nebulaos-build@sha256:... can
only ever resolve to the exact bytes that produced that hash. manifests/dependencies.conf's
BUILD_IMAGE_DIGEST is the one place this is recorded, and build.sh reads it directly — never a
tag.
Because that's what makes the kernel and rootfs reproducible from the pinned Buildroot source.
Baking a pre-built mipsel-buildroot-linux-gnu-gcc into the build image would mean the actual
compiler producing NebulaOS's kernel/rootfs/native-app binaries is no longer traceable to a pinned,
auditable source. This image changes where the build runs, not what Buildroot itself produces.
Unchanged by any of this:
git clone https://github.com/coreflake1/NebulaOS-firmware.git
cd NebulaOS-firmware
./build.shbuild.sh pulls the pinned nebulaos-build image and runs the whole 00–06 pipeline inside it
directly — no nested pellcorp/k1-bash-build/guppydev containers, no /var/run/docker.sock
requirement, no per-stage apt-get. Just Docker or Podman on the host.
docker build -t nebulaos-build:local build-env/To publish a new candidate (never automatically canonical): push to a branch touching
build-env/**, or run .github/workflows/build-environment.yml via workflow_dispatch. It
publishes to ghcr.io/coreflake1/nebulaos-build under a dated/short-SHA tag and prints the
resulting digest. Promotion to canonical is always a separate, deliberate, human step.
Only after all of:
- The candidate image is built from tracked
build-env/Dockerfilecontent and pushed to GHCR. - Its digest is known and recorded.
- A fresh clone is rebuilt using exactly the source refs already accepted as the reference —
same
KERNEL_PIN/KLIPPER_PIN/GUPPYSCREEN_PIN, not newermain, not newer anything. - That rebuild's output is strictly compared against the accepted reference artifacts (hashes,
build-manifest.txtfields,06-verify.sh's content checks). - Every difference found is understood and explicitly classified — either expected/deliberate, or a real regression to fix before promoting.
Only then does a human update BUILD_IMAGE_DIGEST in manifests/dependencies.conf, in its own
reviewed commit. Never automated, never silent.
- Migration A (done): replace the two nested external containers with one NebulaOS-owned image — a change in container ownership/structure only. GuppyScreen's compiler is preserved byte-for-byte.
-
Migration B (investigated, not executed): converge GuppyScreen from its Bootlin musl
toolchain onto Buildroot's own
mipsel-buildroot-linux-gnu-*toolchain. That's a real product/ABI change (musl vs. glibc), not just a packaging change, and was deliberately kept out of Migration A's scope.
-
apt-get installpackages aren't individually version-pinned. Ubuntu's apt repos serve whatever package versions are current when the image is built, not when the Dockerfile is written — so rebuildingbuild-env/Dockerfiletoday vs. a year from now can resolve differentgcc/make/etc. point releases. The Dockerfile itself isn't perfectly bit-reproducible on rebuild. What is reproducible: the published, digest-pinned image is immutable once built — anyone pullingghcr.io/coreflake1/nebulaos-build@sha256:...gets the exact same bytes forever. The pin is on the resulting image, not a promise that rebuilding the Dockerfile reproduces it identically. (pellcorp/k1-bash-build, the container this replaced, had this exact same property and limitation — not a regression, just now made explicit.) - The Bootlin GuppyScreen toolchain and the Ubuntu base image are both pinned (URL + SHA256, and base image digest respectively) — those two layers genuinely are exactly reproducible.
As of the Final Closure mission (2026-08-15): this image is canonical, manifests/ dependencies.conf's old PELLCORP_K1_BASH_BUILD_IMAGE pin is removed, and no script in this repo
references pellcorp/k1-bash-build or ghcr.io/coreflake1/guppydev as a live dependency any
longer. NebulaOS-guppyscreen's own CI has since migrated too — it now builds inside this same
image rather than the standalone guppydev container it used to depend on.
-
Build From Source — the everyday
./build.shentry point - Build Provenance — how to identify exactly what produced a given build
Also tracked as docs/NEBULAOS_BUILD_ENVIRONMENT.md in the repo.
Building
Install / update / recover
Reference