Files
nixos/CLAUDE.md
finn.markwitz 621ca5dde6 docs: sops-nix secrets workflow
Operator runbook for adding a secret, adding a new host, and rotating
keys, plus a pointer from CLAUDE.md's architecture overview.
2026-09-08 15:43:50 +02:00

105 lines
3.8 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Commands
```bash
# Apply configuration (switch/boot/test)
sudo nixos-rebuild switch --flake '.#jupiter'
sudo nixos-rebuild switch --flake '.#mibook'
# Build without switching (CI-style check)
nix build '.#nixosConfigurations.jupiter.config.system.build.toplevel'
# Update all flake inputs
nix flake update
# Format Nix files
nixfmt-rfc-style <file> # or: find . -name '*.nix' | xargs nixfmt-rfc-style
```
## Architecture
This is a flake-parts NixOS configuration for two machines:
- **jupiter** — home server running media/automation services
- **mibook** — laptop running KDE desktop + development tools
### Module Loading Chain
```
flake.nix
└── machines/configuration.nix # flake-parts module; defines nixosConfigurations
├── machines/core/ # base modules applied to every machine
│ ├── core.nix # system packages, locale, timezone
│ ├── network.nix
│ ├── nix.nix
│ ├── sops.nix # sops-nix decryption config, sops/age/ssh-to-age on PATH
│ └── users.nix
├── modules/ # custom NixOS option modules (my.profiles.*, my.hardware.*, my.services.*)
│ ├── environments/ # per-service/app profiles
│ ├── hardware/ # hardware profiles (nvidia, bluetooth, sound, wifi)
│ └── services/ # infrastructure services (vpn, webserver)
└── machines/<name>/
├── configuration.nix # machine-specific NixOS settings
├── environments.nix # enables profiles via my.profiles.* / my.hardware.* options
├── secrets.nix # sops.secrets declared for this host
├── disks.nix
└── hardware-configuration.nix
```
### Secrets (sops-nix)
Secrets are encrypted with sops, decrypted per-host from that host's SSH host
key. `.sops.yaml` defines who can decrypt what; `secrets/<host>.yaml` holds
the encrypted values; `machines/<host>/secrets.nix` declares which secrets
that host exposes and consumes them via `config.sops.secrets.<name>.path`.
Always `git add` a secrets file before `nix build` — untracked files are
invisible to flake evaluation. Full workflow (adding a secret, adding a host,
rotating keys): see [`docs/secrets.md`](docs/secrets.md).
### Profile / Module Pattern
Every module under `modules/` follows the same structure:
```nix
{ config, lib, pkgs, ... }:
let cfg = config.my.profiles.<name>; in
{
options.my.profiles.<name>.enable = lib.mkEnableOption "...";
config = lib.mkIf cfg.enable { ... };
}
```
Namespaces in use:
- `my.profiles.*` — application/service profiles
- `my.hardware.*` — hardware profiles
- `my.services.*` — infrastructure services
Profiles are enabled per-machine in `machines/<name>/environments.nix`.
### Unstable Packages
`pkgs.unstable` is available everywhere via an overlay defined in `machines/configuration.nix`. Use it when a package isn't in the pinned stable channel (`nixpkgs/nixos-25.11`).
### Homepage Dashboard Integration
Modules that expose a web UI can self-register with the homepage dashboard by adding to `my.homepage.services`:
```nix
my.homepage.services = [{
group = "Services";
name = "My Service";
description = "...";
href = "http://${hostName}:PORT";
icon = "si-iconname"; # optional
}];
```
### Adding a New Service Module
1. Create `modules/environments/<name>/default.nix` following the profile pattern above.
2. Add `./environments/<name>` to `modules/environments/default.nix` (or the relevant `default.nix`).
3. Enable it in the target machine's `machines/<name>/environments.nix`.