Nix Builds

Nix Builds

tinyland-nix is the GloriousFlywheel runner lane for reproducible Nix and flake-based workflows.

The current contract is:

  • bootstrap Nix explicitly in self-hosted workflows
  • use Attic and Bazel as acceleration layers
  • do not treat Attic or Bazel as publication surfaces
  • do not treat FlakeHub as part of the primary runner contract today

Runtime Hints

On the Nix runner lane, GloriousFlywheel provides runtime hints such as:

  • ATTIC_SERVER
  • ATTIC_CACHE
  • BAZEL_REMOTE_CACHE
  • NIX_CONFIG

These are useful for cache-aware workflows, but they are not a substitute for installing or verifying the Nix toolchain in the workflow itself.

Preferred: nix-job

Use the composite action when you want GloriousFlywheel to bootstrap Nix and configure the runtime contract for you:

jobs:
  build:
    runs-on: tinyland-nix
    steps:
      - uses: actions/checkout@v6
      - uses: tinyland-inc/GloriousFlywheel/.github/actions/nix-job@main
        env:
          ATTIC_TOKEN: ${{ secrets.ATTIC_TOKEN || '' }}
        with:
          attic-public-key: ${{ vars.ATTIC_PUBLIC_KEY || '' }}
          command: nix build .#default
          push-cache: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && secrets.ATTIC_TOKEN != '' && 'true' || 'false' }}

ATTIC_PUBLIC_KEY tells Nix which cache signing key to trust. Public reads from the shared main cache do not require ATTIC_TOKEN; trusted writes and private-cache reads do. Use attic-enabled: "false" only when a job should not attach Attic at all. When ATTIC_TOKEN is present, nix-job writes it into a temporary netrc-file; Nix access-tokens remains reserved for fetcher-style GitHub/GitLab credentials and is not the Attic read path.

Pull requests should stay read-only. Trusted default-branch jobs may publish only when an ATTIC_TOKEN is present and the workflow explicitly gates push-cache; broad proof workflow writes remain governed by the RustFS/backend write-path guardrails.

Raw Nix Commands

If you want full control over the steps, bootstrap Nix first and then run raw nix commands:

jobs:
  build:
    runs-on: tinyland-nix
    steps:
      - uses: actions/checkout@v6
      - uses: DeterminateSystems/determinate-nix-action@v3
      - run: nix build .#default
      - run: nix flake check

Bootstrap Boundary

tinyland-nix is a Nix-oriented runner lane, not a promise that self-hosted runner image state will always provide nix and related tooling before the workflow starts.

That means:

  • bootstrap Nix in the workflow
  • keep bootstrap overhead separate from build time when benchmarking
  • only then reason about cache acceleration or future publication flows

Acceleration, Not Publication

Current roles:

  • Attic: mutable Nix acceleration layer
  • Bazel remote cache: mutable action/CAS acceleration layer
  • GHCR: current durable OCI publication surface where applicable
  • FlakeHub: future publication/discovery work, not an active Nix runner feature in primary repo surfaces

Memory Envelope Boundary

The current baseline tinyland-nix lane is still an 8Gi runner-pod memory limit, not “all memory on honey.”

That means:

  • ARC can scale the number of Nix runner pods horizontally
  • ARC does not automatically raise the memory limit of one tinyland-nix pod
  • a Rust-heavy or memory-spiky workload can still be OOM-killed inside that 8Gi envelope even when the cluster has abundant free RAM overall

If a workload regularly exceeds that envelope, the right platform answer is usually a heavier additive Nix lane or an explicit limit change, not treating FlakeHub or cache acceleration as a substitute for more memory.

Current additive capability lane:

  • tinyland-nix-heavy is the current shared additive heavy Nix lane in the dev ARC policy
  • it is honey-backed at maxRunners = 2 because honey has the memory headroom for two 64Gi heavy-Nix pods, while sting still needs a proved fast-local Nix scratch/store model before it should host this lane
  • baseline tinyland-nix stays on honey; the bounded tinyland-nix-compute-expansion overflow lane is the first source-owned Sting fast-local Nix proof and uses per-pod /nix plus /home/runner/_work PVCs instead of treating Sting rootfs as the scratch pool
  • use it for recurring Rust-heavy or memory-spiky Nix jobs rather than silently inflating the baseline lane for every workflow

Cold Versus Warm Runs

The first build on a cold cache will be slower. Subsequent runs can benefit from Attic and other cached inputs. That is expected.

When comparing Nix workflows, keep these separate:

  • toolchain bootstrap time
  • cold-cache runtime
  • warm-cache runtime

For KVM-backed VM proofs, the first productized prewarm path is documented in KVM Cache Prewarm. That path publishes selected heavy closures from trusted contexts only; PR jobs keep cache reads but do not get cache-push authority.

GloriousFlywheel