Files
nix-config/hosts/README.md
T
Ryan Yin ad3923df98 feat(git): reach GitHub through gh over HTTPS on agent hosts
Home Manager now owns ~/.config/gh/config.yml on agent hosts; activation moves an existing one to
config.yml.home-manager.backup.

Assisted-by: DeepSeek Harness (claude-opus-5-5)
2026-11-07 23:16:04 +08:00

227 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Hosts
This directory contains all host-specific configurations for my NixOS and macOS systems.
Manual firmware settings are recorded in [`docs/bios.md`](../docs/bios.md), and the shared
Wake-on-LAN workflow is in [`docs/wake-on-lan.md`](../docs/wake-on-lan.md).
## Host Profiles
Every host is exactly one profile. The profile fixes the system module that
`outputs/<system>/src/<host>.nix` imports and the Home Manager role that
`home/hosts/<platform>/<host>.nix` imports. A host directory only adds hardware, networking,
persisted paths and feature switches on top.
| Profile | System module (in outputs) | Home role (in home/hosts) | Hosts |
| --------- | --------------------------------- | ------------------------- | ------------------------------------------- |
| `desktop` | `modules/nixos/desktop.nix` | `home/linux/gui.nix` | `ai`, `shoukei` |
| `agent` | `modules/nixos/agent.nix` | `home/linux/tui.nix` | `aquamarine`, `ruby`, `kana` |
| `server` | `modules/nixos/server/server.nix` | none | `shoryu`, `shushou`, `youko`, k3s, `akane`¹ |
| `darwin` | `modules/darwin` | `home/darwin` | `fern`, `frieren` |
¹ `akane` (aarch64) uses `server-aarch64.nix`; the k3s nodes import `server.nix` from their host
directory.
- **desktop**: Niri session and GUI apps on top of the full TUI stack.
- **agent**: headless, with the full TUI stack from Home Manager (shell, editors, dev toolchains,
cloud CLIs, AI agents with their rules and skills), and nix-ld, rootless Podman and linger from
the system. Computer use (Xvfb + i3, VNC) is part of the profile but off by default. Git reaches
GitHub over HTTPS with the host's own `gh` login, not the owner's SSH key.
- **server**: system services only, no Home Manager.
The `agent` hosts differ only in:
| | `aquamarine` | `ruby` | `kana` |
| ------------ | ------------------------------------------ | ------------------- | ------------------- |
| Computer use | off | on, with cua-driver | on, with cua-driver |
| Hardware | physical; 2x R9700, NPU speech recognition | libvirt guest | libvirt guest |
| Root | tmpfs; `preservation.nix` keeps home state | disk | disk |
`outputs/x86_64-linux/tests/agent-profile` checks the `agent` rows.
### Where a new piece of configuration goes
1. A tool you run from a shell goes to the Home Manager role (`home/base/core`, `home/base/tui`),
never to a host's `environment.systemPackages`.
2. Anything that needs root or a system service (nix-ld, Podman, drivers, systemd units) goes to the
profile's system module, or to a `modules/nixos` module the profile imports.
3. Hardware, networking, the hostname, persisted paths and feature switches go to the host
directory.
A host does not import files from another host's directory; shared code moves under `modules/` or
`home/` instead. Existing exceptions, between machines on identical hardware: `shushou` and `youko`
reuse `12kingdoms-shoryu`'s hardware and preservation files, and `shoukei` reuses `idols-ai`'s
preservation file.
## Current Host Inventory
### Physical Machines
#### `idols` - Main Workstations
Named after characters from "Oshi no Ko":
| Host | Platform | Hardware | Purpose | Status |
| ------------ | --------------- | ---------------------------------------------------- | ------------------ | --------- |
| `ai` | NixOS | i5-13600KF + RTX 4090, 32G DDR5 | Gaming & Daily Use | ✅ Active |
| `aquamarine` | NixOS | Ultra 7 270K Plus + 2x Radeon AI PRO R9700, 96G DDR5 | AI Inference | ✅ Active |
| `kana` | NixOS (libvirt) | Virtual | Run AI Agents | ✅ Active |
| `ruby` | NixOS (libvirt) | Virtual | Run AI Agents | ✅ Active |
| `akane` | NixOS (aarch64) | Virtual (UTM) | aarch64 test VM | ✅ Active |
On 2026-04-27 `ai` was rebuilt on a new platform. The MSI board it was added with in 2023-05, with
the i5-13600KF (the host was originally named `msi-rtx4090`), gave way to the Colorful CVN Z890 ARK
FROZEN + Intel Core Ultra 7 270K Plus. The traces in the history are PR #257 (the NIC moved from
`enp5s0` to `enp130s0`) and PR #258 (Niri output names renamed, `hardware-intel.nix` added). The
kernel moved to `linuxPackages_latest` in `77ca37ea`, the same day but outside #258. The 2×48G DDR5
kit was already in place at that point; the repo has no record of when it went in.
On 2026-10-06 `ai` grew from 2×48G (96G) to 2×48G + 2×16G (128G) across all four DIMM slots, at
DDR5-4800 with XMP off — the only stable setting with four DIMMs on this board. The 16G pair must be
installed first; with the 48G pair in first the board does not POST. It did run, in stretches of one
to two days at a time, before a sudden hard freeze, and resuming from suspend was unreliable too;
the stress test passed and no BIOS setting, DIMM or IMC fault was ever isolated, so 128G in four
DIMMs stayed untrusted.
On 2026-10-13 that platform was split in two. The Z890 board, the 270K Plus, the 2×48G kit and two
Radeon AI PRO R9700 cards became `aquamarine`, a headless inference server; `ai` went back to the
MSI MAG B760M MORTAR board with the i5-13600KF, the 2×16G kit and the RTX 4090. `aquamarine` boots
from the NVMe that used to be `ai`'s `/data` disk. Its name and the address `192.168.5.101` are
reused from the `aquamarine` VM retired on 2026-09-21; that VM's services still run directly on
`youko` (`hosts/12kingdoms-youko/homelab-services/`). Hardware, install and runbook:
[`idols-aquamarine/README.md`](./idols-aquamarine/README.md).
##### Retired
_No physical host in this group is retired. The `aquamarine` VM (NixOS on libvirt, monitoring and
services) was retired on 2026-09-21 and its name was reused for the inference server above._
#### `darwin` - macOS Systems
Named after characters from "Frieren: Beyond Journey's End":
| Host | Platform | Hardware | Purpose | Status |
| --------- | -------- | -------------------------- | ------------ | --------- |
| `fern` | macOS | MacBook Pro M2 13" 16GB | Personal Use | ✅ Active |
| `frieren` | macOS | MacBook Pro M4Pro 14" 48GB | Work Use | ✅ Active |
#### `12kingdoms` - Homelab Servers & Apple Silicon Linux
Named after "Twelve Kingdoms":
| Host | Platform | Hardware | Purpose | Status |
| --------- | -------- | ------------------------------------ | ---------------------- | --------- |
| `shoukei` | NixOS | MacBook Pro M2 | NixOS on Apple Silicon | ✅ Active |
| `shoryu` | NixOS | MoreFine S500+ (AMD Ryzen 7 5825U) | VM Host | ✅ Active |
| `shushou` | NixOS | MinisForum UM560 (AMD Ryzen 5 5625U) | VM Host | ✅ Active |
| `youko` | NixOS | Beelink GTR5 (AMD Ryzen 9 5900HX) | Homelab Core | ✅ Active |
On 2026-09-29 the NVMe SSDs of `youko` and `shushou` were physically swapped, and the 2×4TB USB HDDs
moved with the `youko` role to the other chassis. The reason was Jellyfin: HDR transcoding on the
5625U's Barceló iGPU could not keep up (~0.4–0.8×), while the 5900HX's Cezanne iGPU can (~1.68× for
1080p HDR). So the homelab-core role (all services + the k3s VMs + the HDDs + the UPS) now runs on
the Beelink GTR5 and the k3s VM-host role on the UM560; the other services moving along is a side
effect of swapping the role's disk, not a separate migration. Hostnames, IPs, and state followed the
disks.
### Virtual Machines & Clusters
#### `k8s` - Kubernetes Infrastructure
- **VM Cluster**: 3 physical mini PCs (shoryu, shushou, youko) run the k3s VMs; `akane` is a NixOS
VM under UTM on macOS
- **K3s Testing**: `k3s-test-1` control plane and workers, running as microVMs; placement and
rollout are documented in [`k8s/README.md`](./k8s/README.md)
### External Systems
- **SBCs**: aarch64/riscv64 single-board computers managed in
[ryan4yin/nixos-config-sbc](https://github.com/ryan4yin/nixos-config-sbc)
All my riscv64 hosts:
![](../_img/2023-08-16_nixos-riscv-cluster.webp)
## Naming Conventions
- **idols**: Characters from "Oshi no Ko" anime/manga
- **12kingdoms**: Characters from "Twelve Kingdoms" anime/novel series
- **darwin**: Characters from "Frieren: Beyond Journey's End" anime/manga
- **k8s**: Kubernetes-related systems follow standard naming patterns
## How to Add a New Host
Copy the closest existing host and adapt it. The step-by-step procedure, including the outputs and
networking wiring, secrets, and the eval tests a new host must pass, is in
[`.agents/skills/nix-config-new-host/SKILL.md`](../.agents/skills/nix-config-new-host/SKILL.md).
## CPU Power Policy
Physical hosts get `powersave` from [`power.nix`](../modules/nixos/power.nix); Apple hosts keep
their own `schedutil`. On the active Intel/AMD P-state drivers `powersave` still scales with load,
so this is not a frequency cap.
TuneD is not enabled on any host. It tunes much more than CPU frequency and fits laptops, but our
laptop is a MacBook with its own native support, so it has no use here.
The desktops also run UPower for power-supply reporting: the laptop's battery, and peripheral
batteries on a desktop. It only reports state, and changes no CPU or device setting.
## Deploying VM Hosts
The three VM hosts (`shoryu`, `shushou`, `youko`) put their VMs on the Linux bridge `br0`, with the
physical NIC as a bridge port. NixOS guests run as microVMs (`microvm.nix`); the `k3s-test-1`
cluster is microVMs on top, using Cilium as its pod network (flannel disabled). Full-machine guests
run with qemu-kvm under libvirt instead: `shoryu` is the only host that enables `libvirtd` today
(the agent desktops `kana`/`ruby`). Non-NixOS guests (Ubuntu, Windows, Qubes OS) would take the same
qemu-kvm path; there are none right now.
- `switch` is fine for changes that don't touch the network stack (e.g. journald or other service
settings). Deploy serially (`-p 1`) and re-check VM reachability afterwards.
- Use `boot` + a serial reboot for anything that can drop the network mid-flight — `systemd.network`
/ `br0` changes, nixpkgs updates, or any broad rebuild.
- If a host loses VM networking, check `br0` and the VM taps, or reboot the host.
## Common Build Commands
Use the Just recipes for host configuration checks and builds:
```sh
just eval-host <host>
just build-host <host>
```
`eval-host` only evaluates the configuration. `build-host` builds the system closure without
activating it. Host activation is always explicit: Colmena (`just shoryu`, `just shushou`,
`just youko`, `just aquamarine`) from another machine, or `just local` on the machine itself.
## Distributed Building
I usually run the build command on `Ai` and nix will distribute the build to other NixOS machines,
which is convenient and fast.
When building some packages for riscv64 or aarch64, I often have no cache available because of
various changes under the hood, so I need to build much more packages than usual, which is one of
the reasons why the cluster was originally built, and another reason is distributed building is
cool!
![](../_img/2023-06-17_nix-distributed-building.webp)
![](../_img/2023-06-17_nix-distributed-building-log.webp)
## References
[Oshi no Ko 【推しの子】 - Wikipedia](https://en.wikipedia.org/wiki/Oshi_no_Ko):
![](../_img/idols-family.webp) ![](../_img/idols-ai.webp)
[The Rolling Girls【ローリング☆ガールズ】 - Wikipedia](https://en.wikipedia.org/wiki/The_Rolling_Girls):
![](../_img/rolling_girls.webp)
[List of Twelve Kingdoms characters](https://en.wikipedia.org/wiki/List_of_Twelve_Kingdoms_characters)
![](../_img/12kingdoms-1.webp) ![](../_img/12kingdoms-Youko-Rakushun.webp)
[List of Frieren characters](https://en.wikipedia.org/wiki/List_of_Frieren_characters)