Operator runbook for adding a secret, adding a new host, and rotating keys, plus a pointer from CLAUDE.md's architecture overview.
3.8 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Commands
# 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.
Profile / Module Pattern
Every module under modules/ follows the same structure:
{ 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 profilesmy.hardware.*— hardware profilesmy.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:
my.homepage.services = [{
group = "Services";
name = "My Service";
description = "...";
href = "http://${hostName}:PORT";
icon = "si-iconname"; # optional
}];
Adding a New Service Module
- Create
modules/environments/<name>/default.nixfollowing the profile pattern above. - Add
./environments/<name>tomodules/environments/default.nix(or the relevantdefault.nix). - Enable it in the target machine's
machines/<name>/environments.nix.