shared substitution grid
Find a file
2026-09-26 23:29:36 +02:00
modules set gc policy 2026-09-26 23:29:36 +02:00
.gitignore flake: harmonia+nginx cache server for compute1, client substituter module 2026-09-20 16:22:58 +02:00
flake.lock flake: harmonia+nginx cache server for compute1, client substituter module 2026-09-20 16:22:58 +02:00
flake.nix server: switch harmonia to attic (atticd) for CI push support, token auth, idempotent bootstrap 2026-09-20 18:23:16 +02:00
README.md server: lift nginx body size limit for attic uploads, readme: ci token needs pull + push 2026-09-26 21:29:24 +02:00

💜⚡ P R E E M - N I X - B I N C A C H E ⚡💜

╔═════════════════════════════════════════════════════╗
║ shared substitution grid // one host is the source  ║
║      ==> everyone else skips the rebuild <==        ║
╚═════════════════════════════════════════════════════╝

no more every-box-builds-everything. the cache host holds the store, signs the paths, and every other machine just believes it.

⚡ WHAT THIS IS

a nix flake with two jobs:

  • nixosModules.default — the client module. import it on any box that should trust the cache. adds the substituter and trusted public key.
  • nixosModules.server — the server module. import it on the cache host only. atticd + nginx + ACME TLS, gated by tokens.

this flake doesn't generate or ship secrets - those get distributed manually.

🔌 JACK IN (client side)

{
  inputs.preem-nix-bincache = {
    url = "git+https://forge.darkest.space/mara/preem-nix-bincache.git";
    inputs.nixpkgs.follows = "nixpkgs";
  };

  outputs = { nixpkgs, preem-nix-bincache, ... }: {
    nixosConfigurations.somebox = nixpkgs.lib.nixosSystem {
      modules = [
        preem-nix-bincache.nixosModules.default
        { preem-bincache.client.enable = true; }
      ];
    };
  };
}

somebox now trusts the cache — but it still needs a pull token, or the substituter just gets 401s. mint one on the cache host:

atticd-atticadm make-token --sub clients --validity 5y --pull grid

then drop it into Nix's netrc file (/etc/nix/netrc by default) — attic accepts the token as the basic-auth password:

machine preem-bincache.trollhive.monster
login token
password <pull-token>

🚀 CI PUSH

mint a CI token on the cache host - it needs --pull too, attic checks what the cache already has before pushing:

atticd-atticadm make-token --sub ci --validity 1y --pull grid --push grid

then from CI (requires nixpkgs#attic-client and ci secret):

attic login preem https://preem-bincache.trollhive.monster "$PREEM_PUSH_TOKEN"
attic push preem:grid ./result

🖥️ THE SOURCE (server setup, one-time)

modules = [
  preem-nix-bincache.nixosModules.server
  { preem-bincache.server.enable = true; }
];

TLS is automatic via ACME as long as DNS + ports 80/443 actually reach this host, and the grid cache creates itself on first boot. only manual step left is grabbing its public key:

token=$(atticd-atticadm make-token --sub whoami --validity 5m --pull grid)
attic login preem https://preem-bincache.trollhive.monster "$token"
attic cache info preem:grid   # paste the printed public key into modules/client.nix's `publicKey`

📁 CONSTRUCT ARCHITECTURE

preem-nix-bincache/
├── flake.nix                # nixosModules.default + nixosModules.server
├── modules/
│   ├── client.nix           # substituter + trusted-public-keys
│   └── server.nix           # cache server config for the host
└── README.md                # this transmission