- JavaScript 48%
- Nix 23.7%
- CSS 14.7%
- HTML 8.4%
- Just 5.2%
One line in the shared Home Manager config rather than an edit per host: the
palette is keyed by machine, so `palette.hosts.${hostname}.ramp.mark` gives
green its spring green and blue its blue from the same expression, and red will
get its Transistor red when it lands.
mark is the role the brand book assigns to a prompt hostname. starship only
shows the hostname over SSH by default, which is exactly when knowing the box
matters -- left alone rather than widened.
Verified by reading the generated starship.toml for blue: `style = "bold
#0093ed"`. green's setting evaluates to bold #05ff74; its file cannot be built
here, being aarch64.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|---|---|---|
| design | ||
| home/danzi | ||
| hosts | ||
| modules/common | ||
| .gitignore | ||
| CLAUDE.md | ||
| flake.lock | ||
| flake.nix | ||
| GLOSSARY.md | ||
| justfile | ||
| README.md | ||
gamut
A single NixOS flake covering every machine I run.
Gamut: the complete range of colours a device can reproduce. The hosts are named for colours, so the repo is named for the set of them.
| Host | Machine | Arch | Role |
|---|---|---|---|
red |
laptop | x86_64 | main workstation, dual-boots Arch |
amber |
desktop | x86_64 | heavy/GPU work, NVIDIA, dual-boots Windows, intermittently online |
green |
Raspberry Pi 5 | aarch64 | NAS, NVMe SSD, always on |
blue |
VPS | x86_64 | always-on public host |
Channel: nixpkgs 26.05 (stable) everywhere. Dotfiles via Home Manager.
Usage
Common tasks are just recipes -- run just on its own to list them.
just nix-switch blue # apply this config to blue, permanently
just nix-test blue # apply it only until the next reboot
just rollback blue # undo the last rebuild
just generations blue # what you could roll back to
just gc blue # prune generations older than 30 days
just hs-join # join THIS machine to the tailnet
just hs-join amber # join amber to the tailnet, over SSH
The underlying commands, if you want them directly:
# Rebuild the machine you're sitting at
sudo nixos-rebuild switch --flake .#amber
# Try a change without making it the default boot entry
sudo nixos-rebuild test --flake .#amber
# Deploy to another machine over SSH/Tailscale.
# NB: 26.05 uses --sudo; --use-remote-sudo was the pre-25.05 spelling.
nixos-rebuild switch --flake .#blue --target-host danzi@blue --sudo --ask-sudo-password
# Update pinned inputs
nix flake update
If a rebuild breaks the machine, pick the previous generation from the boot menu. Nothing is destroyed by a bad config.
Layout
flake.nix inputs (pinned) + nixosConfigurations
CLAUDE.md conventions for working in this repo
GLOSSARY.md NixOS terminology
hosts/<name>/ per-machine config, and that machine's INSTALL.md
modules/common/ applies to every host
modules/desktop/ niri, greetd, audio, fonts (Phase 3)
modules/dev/ toolchains (Phase 3)
modules/server/ NAS services (Phase 4)
home/danzi/ Home Manager -- dotfiles, user packages
design/ colour tools and brand book; plain web pages, outside the flake
Per-host install runbooks live beside the host they describe:
hosts/blue/INSTALL.md, hosts/red/INSTALL.md.
Roadmap
Ordered by risk, lowest first -- though green jumped the queue, because the
services it hosts are wanted before the desktop is.
- Phase 0 -- repo skeleton, flake evaluates
- Phase 1 --
blue(VPS). Installed 2026-09-06 with nixos-anywhere. Headscale 0.28 behind Caddy at https://blue.danzi.gay, Let's Encrypt certificate issued automatically. Took three attempts: missing virtio drivers, then a BIOS->UEFI firmware change on reimage. Both recorded inhosts/blue/INSTALL.md - Phase 2 --
green(Pi 5). Installed 2026-09-07 from a running Raspbian, usingnixos-raspberrypibecause the generic aarch64 image will not boot this board. Forgejo serving at https://git.danzi.gay, proxied from blue over the tailnet. Seehosts/green/INSTALL.md - Phase 3 -- rest of
green's services. NFS share at/srv/share(tailnet + LAN, v4 only) and a restic REST server on :8000, append-only, tailnet-only. No backup client yet -- that needsredon NixOS - Phase 4 --
amber(desktop) to a minimal booting box: console + SSH + Tailscale, NVIDIA still commented out. Seehosts/amber/INSTALL.md. Notesdb1is an ESP shared with Windows -- same trap asred - Phase 5 -- the real
amber: NVIDIA, niri desktop, toolchains. Factor shared parts intomodules/desktopandmodules/dev - Phase 6 --
red(laptop), followinghosts/red/INSTALL.md. Highest risk: shared 1 GiB ESP with Arch - Later -- Forgejo Actions runner on
amberfor CI; photo hosting (Immich needs 6 GB RAM, so not on a 2 GB Pi)
Considered and parked
Tangled (https://tangled.org) instead of, or alongside, Forgejo. Some of my peers already use it. Investigated 2026-09-07, left alone for now.
Tangled splits what Forgejo does in one piece: a self-hosted knot holds bare repositories, while identity, issues and pull requests live on AT Protocol and the web UI is tangled.org's appview. The appeal is that collaborators contribute under their own identity, so I never become their account provider, and their contribution history survives my hardware.
Why not now:
- Requires an atproto identity. I use the fediverse via
tech.lgbt, which is ActivityPub -- a separate network, no bridge. Being Bluesky-free means self-hosting a PDS as well as the knot, and possibly still relying on Bluesky's PLC directory unlessdid:webworks end to end (unverified). - Not in nixpkgs. Would add a second third-party flake input (after
nixos-raspberrypi), so green's rebuilds depend on two external repos. - A knot needs to be publicly reachable for both HTTP (port 5555, which blue's Caddy could proxy) and SSH git operations (port 2222). green is behind NAT and Caddy only proxies HTTP, so pushing needs a router forward or a TCP proxy on blue.
- For a handful of peers, a Forgejo account each takes thirty seconds.
The middle path worth revisiting first: use tangled.org's hosted knot with
danzi.gay as the handle, keep green canonical, and push to both remotes. That
gets the collaboration with nothing new running here. The open question is
whether tangled accepts a did:web handle or effectively requires a did:plc
in Bluesky's directory -- that decides whether it is genuinely Bluesky-free.
Secrets (sops-nix) deferred until something actually needs one.
Known rough edges
just nix-switch greenoccasionally fails at activation withsudo: no password was provided, after a long build. Re-running works. Cause not established -- nixos-rebuild pipes the password rather than relying on sudo's timestamp, so a build taking a while should not matter.- Forgejo's SSH clone URLs are tailnet-only (
SSH_DOMAIN = green.tail.internal). Caddy proxies HTTP, not SSH, so outside collaborators must clone over HTTPS. blue's Caddy points at100.64.0.2, green's headscale-assigned address, rather than a name. If green ever re-registers and changes address, that line inhosts/blue/caddy.nixneeds updating.- MagicDNS resolves full names only. headscale runs with
override_local_dns = false, sogreen.tail.internalworks but the search domain is not pushed and baregreendoes not resolve for most tools. That was the right call for a laptop that roams; the cost is using FQDNs. default = "saved"onamber's GRUB is unverified. GRUB needssavedefaultin the entry and it is not established that NixOS emits it for os-prober entries. If Windows does not stay the default after being chosen, pin it by index or title from the generated/boot/grub/grub.cfg.
Things to remember when building the clients
- NFS client support is not automatic. Mounting
green:/srv/shareneeds themount.nfs4helper, not just a kernel that speaks NFS -- without itmountfails with the misleading "mount program didn't pass remote address". On Arch that waspacman -S nfs-utils; onredandamberit needs the equivalent in their NixOS config. Worth putting inmodules/commononce confirmed, since every client wants it. - The restic backup client is still unwritten. green is only the target.
Once
redis on NixOS:services.restic.backups.<name>pointing athttp://green.tail.internal:8000/, backing up~/Projectsand~/Rocketry(and~/.sshis worth considering). The repository password is a real secret, and is the thing that finally justifies setting up sops-nix. restic forget/prunemust run on green, not the client.appendOnlyis deliberate and blocks the client from deleting anything, so retention is a job on green with the service briefly stopped.- Desktop work in progress: the quickshell-based desktop environment is being
designed separately (colour palettes and theming first, outside quickshell).
It lands here as Home Manager config under
home/danzi/once it settles.