nix-config/CLAUDE.md
jasmine 421ac61655
feat(fuchsia): add internet sharing service for 3D printer
Enables internet connection sharing from WiFi (wlo1) to Ethernet (enp34s0)
to provide network access for the 3D printer. Includes DHCP server with
static IP reservation, DNS forwarding through Pi-hole, and NAT configuration.
2025-10-30 14:57:38 +08:00

8.6 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-host
  • nixos/<hostname>/: Host-specific hardware and services
  • home-manager/sajenim/features/: Composable user environment features

Imports Pattern: Each host's configuration.nix composes its full system by:

  1. Importing ../common/global (base system)
  2. Importing selected ../common/optional/* modules
  3. Importing ../common/users/<username> (user accounts)
  4. Importing host-specific services from ./services/
  5. 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 /boot survive 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 from pkgs/
  • modifications: Patches to existing packages (e.g., dmenu theming)
  • unstable-packages: Makes pkgs.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 allowUnfreePredicate in other modules (won't merge)

Flake Inputs

External dependencies include:

  • nixpkgs (25.05 stable), nixpkgs-unstable
  • home-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

  1. Create nixos/<hostname>/ directory
  2. Add configuration.nix and hardware-configuration.nix
  3. Add SSH host keys (ed25519 and RSA) to the host directory
  4. Update flake.nix to add the new nixosConfiguration
  5. 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.nix or configuration.nix
  • Declare persistence paths if using ephemeral root
  • Use agenix for any credentials

Modifying Packages

  • Custom packages: Add to pkgs/ and reference in pkgs/default.nix
  • Patching packages: Add patches to overlays/patches/, modify overlay in overlays/default.nix
  • Unfree packages: Add to allowlist in nixos/common/global/default.nix

Testing Changes

  1. IMPORTANT: Stage new files with git before building or checking
    • Nix flakes only evaluate files tracked in git
    • Run git add <file> for any new files before nix flake check or build
  2. Build configuration: just build <hostname>
  3. Check for evaluation errors: nix flake check
  4. Review changes before switching
  5. Switch: just switch <hostname> (local) or just 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

Network IP Allocation

This infrastructure uses the following IP range scheme to avoid conflicts:

Allocated Ranges:

  • 192.168.50.0/24 - Home router/main LAN
  • 10.1.0.0/24 - Internet sharing from fuchsia (Ethernet to printer)
  • 10.2.0.0/24 - Reserved for future internet sharing from another host
  • 10.3.0.0/24 - Reserved for future internet sharing from another host
  • 10.39.179.0/24 - WireGuard VPN on Raspberry Pi
  • 172.17.0.0/16 - Docker default bridge network (viridian)

Conventions:

  • Internet connection sharing uses 10.N.0.0/24 where N is 1, 2, 3, etc.
  • Gateway host is always 10.N.0.1
  • DHCP pools typically use 10.N.0.2 through 10.N.0.10
  • Keep VPN/tunnel ranges in the 10.30.0.0/16 and higher space

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