101 lines
4.1 KiB
Markdown
101 lines
4.1 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Repository Overview
|
|
|
|
This is a NixOS infrastructure repository managing multiple hosts (servers and personal machines) using a modular Nix configuration approach with SOPS for secrets management and Bento for deployment.
|
|
|
|
## Build and Test Commands
|
|
|
|
```bash
|
|
# Enter development shell (sets up MCP configs)
|
|
nix-shell
|
|
|
|
# Test configuration before deployment (required before PRs)
|
|
./scripts/test-configuration <hostname>
|
|
./scripts/test-configuration -v <hostname> # with --show-trace
|
|
|
|
# Edit encrypted secrets
|
|
nix-shell -p sops --run 'sops hosts/<hostname>/secrets.yaml'
|
|
|
|
# Update secrets keys after adding new age keys
|
|
./scripts/update-secrets-keys
|
|
|
|
# Format Nix files
|
|
nix run nixpkgs#nixpkgs-fmt .
|
|
|
|
# Compute hash for new packages
|
|
nix hash to-sri --type sha256 $(nix-prefetch-url https://example.com/file.tar.gz)
|
|
```
|
|
|
|
## Architecture
|
|
|
|
### Host Structure
|
|
Each host in `hosts/<hostname>/` contains:
|
|
- `configuration.nix` - Main entry point importing modules
|
|
- `hardware-configuration.nix` - Machine-specific hardware config
|
|
- `secrets.yaml` - SOPS-encrypted secrets
|
|
- `modules/` - Host-specific service configurations
|
|
- `fleet.nix` → symlink to root `fleet.nix` (SFTP user provisioning)
|
|
- `utils/` → symlink to root `utils/` (shared modules)
|
|
|
|
Current hosts: `fw` (firewall/router), `nb` (notebook), `web-arm`, `mail`, `amzebs-01`, `nas`
|
|
|
|
### Shared Components (`utils/`)
|
|
- `modules/` - Reusable NixOS modules (nginx, sops, borgbackup, lego, promtail, etc.)
|
|
- `overlays/` - Nixpkgs overlays
|
|
- `pkgs/` - Custom package derivations
|
|
- `bento.nix` - Deployment helper module
|
|
|
|
### Secrets Management
|
|
- SOPS with age encryption; keys defined in `.sops.yaml`
|
|
- Each host has its own age key derived from SSH host key
|
|
- Host secrets in `hosts/<hostname>/secrets.yaml`
|
|
- Shared module secrets in `utils/modules/<module>/secrets.yaml`
|
|
|
|
**IMPORTANT: Never modify secrets files directly.** Instead, tell the user which secrets need to be added and where, so they can edit the encrypted files themselves using:
|
|
```bash
|
|
nix-shell -p sops --run 'sops hosts/<hostname>/secrets.yaml'
|
|
```
|
|
|
|
### Deployment
|
|
The Git runner handles deployment automatically when changes merge to main. A successful `./scripts/test-configuration <host>` dry-build is the gate before pushing.
|
|
|
|
## Custom Packages
|
|
|
|
When creating a new package in `utils/pkgs/`, always include an `update.sh` script to automate version updates. See `utils/pkgs/claude-code/update.sh` for the pattern:
|
|
|
|
1. Fetch latest version from upstream (npm, GitHub, etc.)
|
|
2. Update version string in `default.nix`
|
|
3. Update source hash using `nix-prefetch-url`
|
|
4. Update dependency hashes (e.g., `npmDepsHash`) by triggering a build with a fake hash
|
|
5. Verify the final build succeeds
|
|
|
|
Example structure:
|
|
```
|
|
utils/pkgs/<package-name>/
|
|
├── default.nix
|
|
├── update.sh # Always include this
|
|
└── (other files like patches, lock files)
|
|
```
|
|
|
|
**IMPORTANT: When modifying a custom package** (patches, version updates, etc.), always test by building the package directly, not just running `test-configuration`. The configuration test only checks that the Nix expression evaluates, but doesn't verify the package actually builds:
|
|
|
|
```bash
|
|
# Build a custom package directly to verify it works
|
|
nix-build -E 'with import <nixpkgs> { overlays = [ (import ./utils/overlays/packages.nix) ]; config.allowUnfree = true; }; <package-name>'
|
|
```
|
|
|
|
## Workflow
|
|
|
|
**IMPORTANT: Always run `./scripts/test-configuration <hostname>` after making any changes** to verify the NixOS configuration builds successfully. This is required before committing.
|
|
|
|
## Conventions
|
|
|
|
- Nix files: two-space indentation, lower kebab-case naming
|
|
- Commits: Conventional Commits format (`fix:`, `feat:`, `chore:`), scope by host when relevant (`fix(mail):`). Do not add "Generated with Claude Code" or "Co-Authored-By: Claude" footers.
|
|
- Modules import via explicit paths, not wildcards
|
|
- Comments explain non-obvious decisions (open ports, unusual service options)
|
|
- **Never update `system.stateVersion`** - it should remain at the original installation version. To upgrade NixOS, update the `channel` file instead.
|