Archived
CLAUDE.md's "Composition pattern" section still described the pre-refactor layout (hosts/<host>/configuration.nix as a thin imports list, hardware-configuration wired in from flake.nix) from before the platform x build-type matrix landed. Rewrite it to match the current mkTarget/host.nix architecture and the module moves from the prior commit. Also fixes docs/nix-cache.md, which referenced a modules/nix/ path that never existed in this repo. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01La55Nsss8jZ7ZuzUV9mfot
135 lines
6.4 KiB
Markdown
135 lines
6.4 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Repo purpose
|
|
|
|
Flake-based NixOS configuration for Wayne's LAN servers and workstation. There is
|
|
no application code here — changes are Nix module edits that affect real
|
|
machines when deployed.
|
|
|
|
## Safety rules (read before touching anything)
|
|
|
|
- **Never** run `nixos-rebuild switch|boot|test`, `nixos-install`, `parted`,
|
|
`mkfs`, `mkswap`, `swapon`, `mount`, or any other destructive disk/deploy
|
|
command from an agent session, even if asked indirectly. Deployment is done
|
|
manually by the operator on the target host.
|
|
- Validation is limited to evaluation, linting, formatting checks, and
|
|
`nix build --dry-run --no-link`.
|
|
- Do not add secrets, tokens, private keys, or new password hashes to the repo.
|
|
- This repo currently contains **committed password hashes** (e.g.
|
|
`prepare.sh`, `hosts/nixos/configuration.nix`) and SSH public keys (e.g.
|
|
`modules/nix-cache/server.nix`). The hashes are known tech debt — do not use
|
|
them as a template for new hosts, and flag any *new* secret-like string you
|
|
encounter instead of committing it.
|
|
|
|
## Commands
|
|
|
|
```bash
|
|
# One-time environment bootstrap (installs Nix if missing, prints hosts)
|
|
bash scripts/codex-setup.sh
|
|
|
|
# Full validation: secret grep, nixpkgs-fmt --check, statix lint, eval all hosts
|
|
bash scripts/codex-maintenance.sh
|
|
|
|
# Same, plus a dry-run build (no result symlink) of every host's toplevel
|
|
bash scripts/codex-maintenance.sh dry-run
|
|
|
|
# List the hosts the flake currently exposes
|
|
nix eval --json .#nixosConfigurations --apply builtins.attrNames | jq -r '.[]'
|
|
|
|
# Evaluate a single host without building (fast sanity check)
|
|
nix eval .#nixosConfigurations.<host>.config.system.build.toplevel.drvPath --raw
|
|
|
|
# Dry-run build a single host
|
|
nix build --dry-run --no-link .#nixosConfigurations.<host>.config.system.build.toplevel
|
|
```
|
|
|
|
Formatting/lint tools (`nixpkgs-fmt`, `statix`) are not installed locally; the
|
|
maintenance script pulls them via `nix run github:NixOS/nixpkgs/nixos-25.11#<tool>`.
|
|
There is no test suite — "correctness" here means the flake evaluates and
|
|
`nixpkgs-fmt`/`statix` are clean.
|
|
|
|
## Architecture
|
|
|
|
`flake.nix` is the single entry point. It generates one
|
|
`nixosConfigurations.<platform>-<buildtype>` attribute per target via the
|
|
`mkTarget` function, composed from:
|
|
|
|
```
|
|
nixosSystem {
|
|
modules = [
|
|
disko.nixosModules.disko
|
|
sops-nix.nixosModules.sops
|
|
./modules/common/configuration.nix
|
|
./modules/platforms/${platform}.nix # what it runs on
|
|
./modules/build-types/${buildType}.nix # what it's for
|
|
hostPath # hosts/<name>/host.nix — per-machine identity
|
|
home-manager.nixosModules.home-manager { ... }
|
|
] ++ (client-only modules, for every buildType except "nix-cache" itself)
|
|
}
|
|
```
|
|
|
|
Platforms: `linode`, `proxmox`, `lxc`. Build types: `minimal`, `nix-cache`,
|
|
`server`, `docker`, `gui`, `pxe-boot`. Not every combination is built — e.g.
|
|
`pxe-boot` has no `linode` variant (PXE/DHCP/TFTP need LAN L2 adjacency a
|
|
Linode VPS doesn't have). Treat `flake.nix`'s `generatedTargets` as the source
|
|
of truth for which hosts exist — `README.md`, `AGENTS.md`,
|
|
`docs/flake-lock-automation.md`, and the CI eval workflows
|
|
(`.github/workflows/check-nixos.yml`, `.gitea/workflows/check-nixos.yml`) list
|
|
hosts by hand (or, for the CI workflows, evaluate the flake dynamically) and
|
|
can drift from it, so re-check them against `flake.nix` when adding or
|
|
removing a host.
|
|
|
|
### Composition pattern
|
|
|
|
- `hosts/<name>/host.nix` — per-machine identity **only**: hostname, hostId,
|
|
per-machine secrets, `system.stateVersion`. These files carry no `imports`
|
|
of their own beyond narrow parameterized helpers (see
|
|
`modules/beszel/host-token.nix` below) — all shared behavior comes from the
|
|
platform/build-type modules composed in `flake.nix`, not from the host file.
|
|
- `modules/platforms/{linode,proxmox,lxc}.nix` — platform-specific config:
|
|
boot method, guest tooling, and (for linode/proxmox) the hypervisor-specific
|
|
hardware config, imported directly by the platform module itself
|
|
(`../hardware-configuration/vm/{proxmox,linode}.nix`) — **not** wired in
|
|
from `flake.nix`. `lxc.nix` has no hardware-configuration counterpart since
|
|
containers share the host kernel.
|
|
- `modules/build-types/*.nix` — what a system is for:
|
|
minimal/server/docker/gui/pxe-boot/nix-cache.
|
|
- `modules/common/configuration.nix` — base NixOS config imported by every
|
|
host: locale, users, nix settings, git.
|
|
- `modules/common/home.nix` / `hosts/nixos/home.nix` — Home Manager config for
|
|
the `nixos` user; the `nixos` workstation (`gui` build type) has its own,
|
|
other hosts share `modules/common/home.nix`.
|
|
- `modules/disko/proxmox.nix` — declarative disk layout (GPT: ESP + swap +
|
|
ext4 root) via disko, used by all Proxmox-VM hosts.
|
|
- `modules/boot/efi.nix` — systemd-boot + EFI vars, paired with the disko module.
|
|
- `modules/nix-cache/{client,server,remote-builder-client}.nix` — binary cache
|
|
substituter + SSH remote-builder wiring; see `docs/nix-cache.md` for the
|
|
full design (per-host local stores, no shared `/nix/store`, and how the
|
|
`nixremote` signing/SSH keys fit together).
|
|
- `modules/beszel/host-token.nix` — parameterized helper module
|
|
(`{ name, sopsFile }`) that wires a host's beszel-agent sops secret/template
|
|
and `environmentFile`; used by `hosts/server/host.nix` and
|
|
`hosts/nix-cache/host.nix` to avoid duplicating that boilerplate.
|
|
- `modules/tailscale/`, `modules/docker/`, `modules/networking/`,
|
|
`modules/traefik/`, `modules/services/*` — single-purpose, single-host
|
|
feature modules (e.g. `docker/enable-service.nix`,
|
|
`services/zfs/enable-service.nix`). Grep `modules/build-types/*.nix` for
|
|
each build type's `imports` list to see which modules apply where.
|
|
|
|
New host = new `hosts/<name>/host.nix` + a matching
|
|
`mkTarget { platform; buildType; hostPath; }` entry added to `flake.nix`'s
|
|
`generatedTargets`, composed from existing `modules/*` pieces rather than
|
|
duplicating config.
|
|
|
|
### Other docs worth reading before touching these areas
|
|
|
|
- `docs/nix-cache.md` — nix-cache binary cache/remote-builder design and key
|
|
handling.
|
|
- `docs/pxe-boot.md` — the `pxe-boot` host's iPXE/TFTP/HTTP boot chain and
|
|
directory layout under `/srv/pxe`.
|
|
- `docs/flake-lock-automation.md` — how `flake.lock` updates flow through CI
|
|
(scheduled `nix flake update` PR + host-eval-on-PR workflow) and why hosts
|
|
should track the committed lock file rather than `nixos-rebuild --upgrade-all`.
|