fleet-pins
Shared nixpkgs pin for the server fleet — ensures binary cache alignment
Overview
Centralized nixpkgs version pin shared by all servers in the fleet. Ensures consistent package versions and binary cache hits across armer, howard, emmett, micron, bim, and mermaid.
Design intent
All per-host pins (nixpkgs-armer, nixpkgs-emmett, etc.) currently
follows = "nixpkgs" — there is zero divergence across the fleet today.
This is intentional: a single shared revision maximises binary-cache hit rate
and keeps the fleet in a known-good, consistent state.
The per-host inputs exist as named extension points so that any individual
host can be broken away from the fleet default by changing its follows to a
direct url. Until a host actually needs to diverge, the pins simply track
the default.
Usage
Reference in your flake inputs:
inputs.fleet.url = "git+https://git.oleks.space/oleks/fleet-pins";
Then use fleet.inputs.nixpkgs as your nixpkgs source.
After changing the pin: which projects to re-lock
Changing the pin here (editing nixpkgs.url + committing) does nothing on
its own — every consumer has its own flake.lock that still points at the
old fleet-pins revision until you explicitly re-lock it:
nix flake update fleet # or `fleet-pins`, whatever the input is named
Consumers come in two classes, and they must be re-locked in the right order or you get silent binary-cache divergence (downstream packages built against the old nixpkgs → cache misses / rebuilds from source).
Class A — intermediate exporters (re-lock these FIRST, bottom-up)
These flakes export prebuilt packages / overlays that other flakes consume.
Because their .packages are evaluated in their own nixpkgs context (not the
consumer's), a stale lock here means the consumer pulls packages built on the
old pin even after the consumer itself re-locks. Re-lock + push these
before any host that consumes them.
Re-lock these (input name in parentheses), then commit + push:
oleks/parity-lib(fleet) — parity publish-app builders. No fleet deps; re-lock first. Consumed by woodpecker-peek + ~51 parity repos.oleks/woodpecker-peek(fleet) — tray app. Depends on parity, so alsonix flake update parityhere.oleks/flake-hub=oleks-nixpkgs(fleet-pins) — exports metamcp, xonsh, stalewood, woodpecker-peek, nix-deps, hyprspace/gcc15 overlays. Depends on parity + woodpecker-peek — also update those two inputs here.oleks/oleks-nix-tools(fleet) — exports nix-dead-paths, nix-gc-roots, nix-store-shadows. No fleet deps.
Canonical order: parity-lib → woodpecker-peek → flake-hub &
oleks-nix-tools → host configs. In each exporter, also nix flake update
its nested parity / woodpecker-peek inputs so the nested fleet is picked
up (otherwise a stale nested fleet keeps that subtree on the old nixpkgs).
Class B — leaf consumers (per-host NixOS configs)
These consume fleet-pins only to set their system nixpkgs. They carry no exported packages, so they only need a re-lock when you want that host to move to the new pin — typically as part of its deploy. Each host is independent; re-locking one does not affect the others.
servers/emmett, servers/armer, servers/howard, servers/bim,
servers/micron, servers/mermaid-gpu, servers/kotkan, plus non-fleet
NixOS flakes that pin here (gvisor, gvisor-s390x/test-services).
A host will not fully align until all the Class-A exporters it depends on are re-locked and pushed first. Verify with a transitive check — every
nixpkgs*node in the host'sflake.lockshould resolve to the new rev except the intentional standalone pins (e.g. emmett'snixpkgs-hyprland,nixpkgs-gemini,nixpkgs-opencode).
Everything else (package repos, ~51 parity repos)
Many standalone package repos pin here purely for cache alignment of their own
builds (browser-automation, mcp-chrome, builder-arbitrage, the parity
repos, the helms/* charts, etc.). Re-lock these when you next build/republish
them — they are not in any host's runtime closure, so they don't block a fleet
deploy.