Adding a host
Copy the closest existing host and change what differs. The current inventory and naming scheme are in hosts/README.md.
Core rules
- Three names, decided up front. The directory (
hosts/idols-ai/), the hostname (hostName = "ai"), and the configuration name (ai-niri) differ. Servers use the hostname as the configuration name; Niri desktops append-niri, becausejust nirideploys$(hostname)-niri. Thehostnameeval test encodes this. - Secrets come from another repository. The new host decrypts nothing until its host key is a
recipient in
nix-secrets; see thenix-config-secretsskill. A new desktop also needs its synced dotfiles restored before the first switch, or the shell starts without them. - The shared policy modules are not optional. Several eval tests assert a policy for every
configuration, so an under-wired host fails
just testinstead of failing in production. - Build before you install.
just test,just eval-host <name>, andjust build-host <name>pass before anything is partitioned or flashed.diskodestroys the target disk, and partitioning and installing are user-run actions on a device the user has confirmed.
1. Pick the template
- Desktop workstation:
hosts/idols-ai/+outputs/x86_64-linux/src/idols-ai.nix - Homelab server / VM host:
hosts/12kingdoms-shoryu/+outputs/x86_64-linux/src/12kingdoms-shoryu.nix - Apple Silicon Linux:
hosts/12kingdoms-shoukei/+outputs/aarch64-linux/src/12kingdoms-shoukei.nix - macOS:
hosts/darwin-fern/+outputs/aarch64-darwin/src/fern.nix(darwinConfigurations, no Colmena) - MicroVM guest:
hosts/k8s/k3s-test-1-worker-1/+outputs/x86_64-linux/src/k3s-test-1-worker-1.nix
A MicroVM guest is also registered in its VM host's microvm.nix; deploy it with the procedure in
WA-026 of WORKAROUNDS.md, not just microvm-deploy. On a VM host with
the br0 bridge it also needs a systemd.network.networks unit that attaches the guest's tap to
br0; the tap name comes from the guest IP (192.168.5.116 to vm116). Some guest outputs also
expose a Colmena node for evaluation or other workflows; do not assume the physical-host deployment
is done through Colmena.
2. Files to create or edit
hosts/<dir>/default.nix- setshostNameand imports the host's modules. Some hosts (shoryu,shushou,youko,akane) importmylib.scanPaths ./., which pulls in every other.nixfile in the directory; keep scratch files out of those.hosts/<dir>/hardware-configuration.nix- generated on the target machine (nixos-generate-config --show-hardware-config), never copied from another host. Where the layout is declarative, adddisko-fs.nixand record the install command in the host'sREADME.md, ashosts/idols-ai/README.mddoes.home/hosts/linux/<name>.nixorhome/hosts/darwin/<name>.nix- only for a host with Home Manager; otherwise leavehome-modulesout.outputs/<system>/src/<name>.nix- add the output types appropriate to the host:nixosConfigurations.<name>for NixOS,darwinConfigurations.<name>for macOS, and apackages.<name>installer image only where the platform provides one. Addcolmena.<name>only for a host deployed through Colmena; it then needstags,ssh-user, and usuallytargetHost. MicroVM guests also need the VM-hostmicrovm.nixregistration. Keep the leading comment about unusedargs: haumea passes them lazily and they are still required.vars/networking.nix-hostsAddr.<name> = { iface; ipv4; }for a LAN host. That entry drives the static address, the SSHHostalias used for remote builds, andknown_hosts, so a wrongifacetakes the host offline at activation. Skip it for a DHCP or mobile host;homeOnly = trueonly drops the SSH alias and the local exporters, notknown_hostsor the scrape targets. If the host enablesmodules.networking.mihomoand runs systemd-resolved, it needs a DNS takeover tied to mihomo's lifecycle (resolvectl dns/revertinExecStartPost/ExecStopPost, seehosts/idols-ai/default.nix); a static link DNS would kill DNS when mihomo dies.hosts/README.md- add the host to the inventory.
Pin service user and group ids (service-user-ids.nix, as on shoryu) before the host has state on
disk. A dynamically allocated id that moves on a later rebuild orphans the files it owned
(9187e4d9 fix(youko): pin dynamically-allocated service uid/gid (#320)).
3. Tests that fail until the host is wired
outputs/README.md lists which eval tests check every configuration and which list hosts by name:
hostname: a new-niriconfiguration needs aspecialExpectedentry, in the test for its platform (ai-niriin x86_64-linux,shoukei-niriin aarch64-linux).security-*,kernel,nix-system-features: apply to every configuration automatically.home-manager,btrbk, and the other host-listing tests: add the host if it should be covered.
just test fails (non-zero) unless the suite returns true.
4. Install and deploy
- First install: boot the ISO, partition with disko, install, then deploy normally. Partitioning,
formatting, and installing destroy the target disk, so they are user-run actions on a device the
user confirmed: check
lsblk/findmntfirst, name the exact device, and get authorization for it before anydestroy,format,mount. Follow nixos-installer/README.md and the host's own README. - Remote hosts:
just col <tag>or the host's own recipe, once its key is a secrets recipient. Deploying is a separate impactful action; use thenix-config-updateskill's staged deployment (confirm the target, preview the closure, and get authorization). - The machine you are on: the user runs
just localorjust niri.
5. Verify
ssh <name> true, thensystemctl --failedandjournalctl -b -p erron the host.- Secrets decrypted, checked by mode and owner only.
- The role works: the service, VM, or desktop the host exists for.


