tinyFragments

The NixOS fleet

Twelve computers, one description.

The fleet dashboard on a phone: one certificate warning at the top, every other check green.

The problem

Our household runs on a dozen computers: my work laptop, the family's laptops, a recording PC, two little Raspberry Pis and a server in a data centre. Set up by hand, each one slowly drifts away from the others. A fix made on one never reaches the rest, and after a year nobody remembers how any of them was built.

What it does now

Where AI came in

Most of the description is written by Claude Code, an AI assistant that works in my terminal. I decide what each machine should do, review every change, and check it on the real hardware. The project keeps its own handbook, and the AI has to update it with every change, so each session starts from what's written down instead of from guesswork.

How it's built
li4, a public server, is the lighthouse for an overlay network joining nine home machines. tinydaw backs everything up offsite. sparelt and woab01 are not on the overlay.
The fleet. Hostnames are real; every address is a documentation address.

Shape

  • One Nix flake describes all twelve machines. Each host has a module list in flake.nix. The 54 shared modules are switched on per host through a local.* option namespace, and home-manager carries each person's desktop.
  • Secrets are encrypted in the repo with sops-nix, per host, so the repo can be cloned anywhere without exposing them.

The network: Nebula, not Tailscale

li4, a small Linode VM, is the lighthouse and relay. Every other machine finds the rest through it and then talks to them directly.

The fleet started on Tailscale. I built a self-hosted headscale server to drop the vendor account, and abandoned it the next day (2026-09-11): an Android client shipped a protocol version no headscale release understood, and there was nothing installable that would fix it. Nebula has no control plane to fall out of step with. A machine either holds a valid certificate and can reach a lighthouse, or it doesn't, and both halves can be checked locally.

Hosts carry groups in their certificates. tinyclaw, the AI assistant, is in group agent, and li4's firewall lets that group reach one port and nothing else. sparelt isn't on the overlay yet, and woab01 stays off it entirely, by design.

Services that should never be public (the password vault, the dashboards) answer only on the overlay. Their TLS comes from a private certificate authority, name-constrained to the overlay's own domain, so there's no public DNS record and no ACME account.

Deploys

./rebuild <host>, ./rebuild fleet or ./rebuild hypr runs from my laptop. It builds on tinydaw, the recording desktop, and switches each machine over ssh. A laptop that is asleep gets its system built and held, then shipped on the next run. Every run posts a record to the dashboard's deploy log, and when Claude runs it, the /rebuild skill pings me on Matrix as each host finishes.

tinydaw also runs a binary cache (harmonia). The other machines pull from it before cache.nixos.org, so a package is built or downloaded once per fleet, not once per laptop.

Backups

Every machine sends a nightly restic backup to tinydaw over the overlay. Each night tinydaw mirrors that store offsite, and the snapshots on the far end are what protects against tinydaw itself failing. A failed job emails me.

Keeping the AI honest

Every .nix file opens with a header that says what it is for and why, including what was tried and reverted. That's often the most useful comment in the file. A docs/ wiki covers what no single file can say, and its tables (the host-to-module matrix, the option list) are generated from the tree by a script with a --check mode. The repo's CLAUDE.md tells the AI that a change isn't finished until the header, the generated tables and a freshness stamp are updated, and that a commit doesn't authorise a deploy.

670 commits since 2026-04-22. The repository is private, so there are no links to it here.