Create comprehensive documentation for Claude Code instances working in this repository, including build commands, architectural patterns, and workflows.
7.7 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Build and Deployment Commands
Building Configurations
# Build a NixOS configuration (creates ./result symlink)
just build <hostname>
# or
nixos-rebuild build --flake .#<hostname>
# Build home-manager configuration
home-manager build --flake .#sajenim@<hostname>
Deploying Changes
# Apply NixOS configuration locally (requires sudo)
just switch <hostname>
# or
sudo nixos-rebuild switch --flake .#<hostname>
# Deploy to remote host
just deploy <hostname>
# or
nixos-rebuild switch --flake .#<hostname> --target-host <hostname> --use-remote-sudo
# Apply home-manager configuration
home-manager switch --flake .#sajenim@<hostname>
Code Quality
# Format all Nix files using alejandra
nix fmt
# Check flake and evaluate all configurations
nix flake check
Secret Management
# Rekey secrets using YubiKey (after adding/modifying secrets)
agenix-rekey edit <secret-name>
agenix-rekey rekey
Architecture Overview
Flake Structure
This is a NixOS flake-based configuration managing two hosts:
- fuchsia: Desktop workstation (gaming, development, XMonad)
- viridian: Server (multimedia, services, containers)
The flake follows the standard structure from Misterio77's starter configs.
Configuration Layers
NixOS System Configuration (nixos/):
nixos/
├── common/
│ ├── global/ # Base system config for all hosts
│ │ ├── age.nix # Agenix secret management with YubiKey
│ │ ├── env.nix # Environment variables
│ │ ├── nix.nix # Nix daemon, flakes, garbage collection
│ │ └── ssh.nix # SSH server config
│ ├── optional/ # Opt-in features
│ │ ├── ephemeral-btrfs.nix # Impermanence with btrfs root wipe
│ │ ├── persist.nix # Persistence paths for ephemeral root
│ │ └── yubikey.nix # YubiKey support
│ └── users/ # User-specific system settings
├── fuchsia/
│ ├── configuration.nix
│ └── services/ # Desktop services (X11, pipewire, flatpak, etc.)
└── viridian/
├── configuration.nix
├── services/ # Server services (traefik, minecraft, IRC, etc.)
└── multimedia/ # *arr stack (sonarr, radarr, jellyfin, etc.)
Home-Manager User Configuration (home-manager/):
home-manager/sajenim/
├── global/ # Base home config
├── features/ # Modular user features
│ ├── cli/ # Shell, terminal utilities
│ ├── desktop/ # GUI applications, window manager
│ ├── editors/ # Text editors configuration
│ ├── games/ # Gaming-related configs
│ ├── printing/ # Printer utilities
│ └── university/ # Academic tools
├── fuchsia.nix # Desktop profile
└── viridian.nix # Server profile (minimal)
Key Architectural Patterns
Module Organization: Configuration is split between:
nixos/common/global/: Imported by ALL hosts (mandatory base config)nixos/common/optional/: Opt-in features imported per-hostnixos/<hostname>/: Host-specific hardware and serviceshome-manager/sajenim/features/: Composable user environment features
Imports Pattern: Each host's configuration.nix composes its full system by:
- Importing
../common/global(base system) - Importing selected
../common/optional/*modules - Importing
../common/users/<username>(user accounts) - Importing host-specific services from
./services/ - Setting host-specific options (hostname, firewall, etc.)
Impermanence: Uses opt-in persistence with ephemeral btrfs root:
- Root filesystem (
/) wiped on every boot - Only
/nix,/persist, and/bootsurvive reboots - Services must explicitly declare what to persist in
/persist - Secrets use persistent SSH keys at
/persist/etc/ssh/for decryption
Secret Management:
- Encrypted with agenix using host SSH keys
- Master key stored on YubiKey for rekeying
- Rekeyed secrets stored in
nixos/common/global/secrets/rekeyed/<hostname>/ - Decryption happens during system activation using persistent SSH keys
Overlays: Applied globally via nixos/common/global/default.nix:
additions: Custom packages frompkgs/modifications: Patches to existing packages (e.g., dmenu theming)unstable-packages: Makespkgs.unstable.*available for newer versions
Unfree Packages: Allowlist is centralized in nixos/common/global/default.nix
- Default policy: only free software
- Exceptions listed explicitly (steam, minecraft-server)
- Do NOT use
allowUnfreePredicatein other modules (won't merge)
Flake Inputs
External dependencies include:
nixpkgs(25.05 stable),nixpkgs-unstablehome-manager(follows nixpkgs)agenix,agenix-rekey(secret management)impermanence(ephemeral root filesystem)crowdsec(security)nixvim(personal Neovim config, external flake)xmonad-config(personal XMonad config, external flake)nix-minecraft(declarative Minecraft server)
Personal flakes (nixvim, xmonad-config) are maintained in separate repositories
and imported as flake inputs. They are updated independently via nix flake update.
Working with This Configuration
Adding a New Host
- Create
nixos/<hostname>/directory - Add
configuration.nixandhardware-configuration.nix - Add SSH host keys (ed25519 and RSA) to the host directory
- Update
flake.nixto add the newnixosConfiguration - Configure secrets: update age.rekey to include new host key
Adding a Service
Services are organized by host in nixos/<hostname>/services/:
- Create a subdirectory for complex services (e.g.,
traefik/) - Each service gets its own
default.nix - Import in
nixos/<hostname>/services/default.nixorconfiguration.nix - Declare persistence paths if using ephemeral root
- Use agenix for any credentials
Modifying Packages
- Custom packages: Add to
pkgs/and reference inpkgs/default.nix - Patching packages: Add patches to
overlays/patches/, modify overlay inoverlays/default.nix - Unfree packages: Add to allowlist in
nixos/common/global/default.nix
Testing Changes
- Build configuration:
just build <hostname> - Check for evaluation errors:
nix flake check - Review changes before switching
- Switch:
just switch <hostname>(local) orjust deploy <hostname>(remote)
Managing Secrets
- Secrets are encrypted per-host and stored in
nixos/common/global/secrets/rekeyed/<hostname>/ - Edit secrets:
agenix-rekey edit <secret-name> - After editing, rekey all hosts:
agenix-rekey rekey - YubiKey required for rekeying operations
- Host SSH keys at
/persist/etc/ssh/are used for automatic decryption
Important Conventions
Line Length
Keep all Nix code to a maximum of 100 characters per line for consistency.
Module Naming
- System-level services:
nixos/<hostname>/services/<service-name>/default.nix - User-level features:
home-manager/sajenim/features/<category>/<feature>.nix
Persistence Declarations
When adding services to hosts with ephemeral root, declare persistence:
environment.persistence."/persist" = {
directories = [
"/var/lib/service-name"
];
files = [
"/var/lib/service-name/config.conf"
];
};
Comments
This codebase uses structured comments to explain configuration choices:
- Block comments at file top explain module purpose
- Inline comments explain non-obvious configuration decisions
- Group related options with visual separators when helpful