diff --git a/.gitea/workflows/check-nixos.yml b/.gitea/workflows/check-nixos.yml index 5edd218..2b8c549 100644 --- a/.gitea/workflows/check-nixos.yml +++ b/.gitea/workflows/check-nixos.yml @@ -20,7 +20,7 @@ jobs: - name: Evaluate all NixOS hosts run: | set -euo pipefail - for host in nixos docker kuma server nix-cache nix-minimal pxe-boot; do + for host in nixos docker server nix-cache nix-minimal pxe-boot linode-minimal; do echo "Evaluating ${host}" nix --extra-experimental-features 'nix-command flakes' eval \ ".#nixosConfigurations.${host}.config.system.build.toplevel.drvPath" --raw diff --git a/.github/workflows/check-nixos.yml b/.github/workflows/check-nixos.yml index 5edd218..2b8c549 100644 --- a/.github/workflows/check-nixos.yml +++ b/.github/workflows/check-nixos.yml @@ -20,7 +20,7 @@ jobs: - name: Evaluate all NixOS hosts run: | set -euo pipefail - for host in nixos docker kuma server nix-cache nix-minimal pxe-boot; do + for host in nixos docker server nix-cache nix-minimal pxe-boot linode-minimal; do echo "Evaluating ${host}" nix --extra-experimental-features 'nix-command flakes' eval \ ".#nixosConfigurations.${host}.config.system.build.toplevel.drvPath" --raw diff --git a/AGENTS.md b/AGENTS.md index 793f61c..2eda899 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -9,11 +9,11 @@ The flake currently exposes these NixOS configurations: - `nixos` - `docker` -- `kuma` - `server` - `nix-cache` - `nix-minimal` - `pxe-boot` +- `linode-minimal` Do not deploy, switch, reboot, repartition, format disks, or run destructive install commands from this repository unless explicitly asked. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..818e2e5 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,114 @@ +# 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..config.system.build.toplevel.drvPath --raw + +# Dry-run build a single host +nix build --dry-run --no-link .#nixosConfigurations..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#`. +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 defines one `nixosConfigurations.` +attribute per machine, each built the same way: + +``` +nixosSystem { + modules = [ + disko.nixosModules.disko + ./hosts//configuration.nix # host-specific config + ./modules/hardware-configuration/vm/.nix + home-manager.nixosModules.home-manager { ... } + ]; +} +``` + +Hosts currently defined in `flake.nix`: `nixos`, `docker`, `server`, +`nix-cache`, `nix-minimal`, `pxe-boot`, `linode-minimal`. Treat `flake.nix` 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 and can drift from it, so re-check them against `flake.nix` when +adding or removing a host. + +### Composition pattern + +Every host's real configuration lives in `hosts//configuration.nix`, +which is a thin list of `imports` pulling in reusable pieces from `modules/`: + +- `modules/common/configuration.nix` — base NixOS config imported by (almost) + every host: locale, users, nix settings, git. Nearly always the first import. +- `modules/common/home.nix` / `hosts//home.nix` — Home Manager config for + the `nixos` user; the `nixos` workstation 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/hardware-configuration/vm/{proxmox,linode}.nix` — hypervisor-specific + hardware config, wired in from `flake.nix` (not from the host file). +- `modules/nix-cache/{client,server}.nix` + `modules/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/tailscale/`, `modules/docker/`, `modules/beszel/`, + `modules/services/*` — single-purpose, single-host feature modules (e.g. + `docker/enable-service.nix`, `services/zfs/enable-service.nix`, + `beszel/enable-agent.nix` for monitoring). Grep `hosts/*/configuration.nix` + for the `imports` list to see which modules apply to a given host. + +New host = new `hosts//configuration.nix` + a matching block added to +`flake.nix`'s `nixosConfigurations`, 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`. diff --git a/README.md b/README.md index 1ecb38e..bfddd70 100644 --- a/README.md +++ b/README.md @@ -11,11 +11,11 @@ This flake currently defines: | --- | --- | | `nixos` | Main NixOS workstation / Cinnamon desktop | | `docker` | Docker host for the main container stack | -| `kuma` | Docker-enabled Uptime Kuma style host | | `server` | Storage, NFS, backup, and monitoring exporter host | | `nix-cache` | Local Nix binary cache and remote builder | | `nix-minimal` | Minimal NixOS host profile with SSHFS tooling | | `pxe-boot` | HTTP/iPXE boot asset host | +| `linode-minimal` | Minimal NixOS host profile for Linode VPS instances | List hosts with: diff --git a/docs/flake-lock-automation.md b/docs/flake-lock-automation.md index 6867c24..5bec8cf 100644 --- a/docs/flake-lock-automation.md +++ b/docs/flake-lock-automation.md @@ -11,11 +11,11 @@ and to verify that declared NixOS hosts still evaluate after dependency updates. - A separate CI workflow evaluates every configured host before merge: - `nixos` - `docker` - - `kuma` - `server` - `nix-cache` - `nix-minimal` - `pxe-boot` + - `linode-minimal` ## Why hosts should stop using `--upgrade-all`