# NIXOS CONFIGURATION KNOWLEDGE BASE

**Generated:** 2025-12-31 16:13:40 UTC  
**Commit:** ebc8291  
**Branch:** HEAD

## OVERVIEW
Personal NixOS configuration managing 6 hosts (4 servers, 2 desktops) using flakes, agenix secrets, and feature-based home-manager setup.

## STRUCTURE
```
./
├── flake.nix              # Main entry: host definitions, inputs, outputs
├── secrets.nix            # Agenix public key mappings
├── hosts/
│   ├── common/            # Shared: base config, users, extraServices, ports
│   ├── m3-atlas/          # Server: 20+ containerized services with Traefik
│   ├── m3-helios/         # Server: AdGuard, internal routing
│   ├── m3-ares/           # Desktop: NVIDIA GPU, Btrfs
│   ├── m3-kratos/         # Desktop: AMD GPU, ZFS
│   └── m3-aether/         # Cloud VM
├── home/
│   ├── common/            # Home-manager base config
│   ├── features/          # Modular feature toggles (cli, desktop, coding)
│   └── m3tam3re/          # Per-host user configs
├── modules/               # Custom NixOS/home-manager modules
├── overlays/              # Package overlays (stable, locked, pinned, master)
├── pkgs/                  # Custom package definitions
└── secrets/               # Agenix encrypted .age files (19 secrets)
```

## WHERE TO LOOK

| Task | Location | Notes |
|------|----------|-------|
| Add new host | `flake.nix` + `hosts/<name>/` | Copy template from m3-atlas (server) or m3-ares (desktop) |
| Add service to m3-atlas | `hosts/m3-atlas/services/` | See containers/ for Podman + Traefik pattern |
| Configure desktop features | `home/features/desktop/` | Feature toggles with mkEnableOption |
| Add CLI tool | `home/features/cli/` | Fish + Nushell integration expected |
| Manage secrets | `secrets.nix` + `agenix -e` | SSH keys defined in secrets.nix |
| Define ports | `hosts/common/ports.nix` | Centralized port registry |
| Add user | `hosts/common/users/` | Shared across all hosts |
| Custom packages | `pkgs/default.nix` | Exposed via flake outputs |

## CONVENTIONS

### Secrets (agenix)
- **Create**: `agenix -e secrets/<name>.age` after adding keys to `secrets.nix`
- **Reference**: `config.age.secrets.<name>.path` in service configs
- **Pattern**: Service env files use `environmentFiles = [config.age.secrets.<service>-env.path]`

### Service Organization
- **Native services**: `hosts/<host>/services/<service>.nix`
- **Containers**: `hosts/<host>/services/containers/<service>.nix`
- **Traefik integration**: All m3-atlas services include dynamic config for SSL + routing
- **Networking**: Containers use dedicated `web` network (10.89.0.0/24) with static IPs

### Port Management
- **Registry**: All ports defined in `hosts/common/ports.nix`
- **Access**: `config.m3ta.ports.get "service-name"`
- **Convention**: Internal services use 3000-3020 range

### Home-Manager Features
- **Enable**: `features.<category>.<feature>.enable = true` in user config
- **Categories**: `cli`, `desktop`, `coding`
- **Pattern**: Features are opt-in modules with default.nix aggregators

### Multiple nixpkgs Inputs
- **stable**: 25.11 release
- **locked/pinned**: Specific commits for compatibility
- **master**: Bleeding edge
- **m3ta-nixpkgs**: Custom local overlay at `path:/home/m3tam3re/p/nix/nixpkgs`

## COMMANDS
```bash
# Build/deploy specific host
sudo nixos-rebuild switch --flake .#m3-ares

# Build/deploy current host
sudo nixos-rebuild switch --flake .#$(uname -n)

# Home-manager update
home-manager --flake . switch

# Update all flake inputs
nix flake update

# Add/edit secret
agenix -e secrets/<name>.age

# Infrastructure shell (OpenTofu)
nix develop .#infraShell

# Check configuration (no activation)
nixos-rebuild dry-build --flake .#<hostname>
```

## TRAEFIK PATTERNS (m3-atlas only)

### SSL Termination
- **Provider**: Godaddy DNS challenge
- **Cert storage**: `/var/lib/traefik/acme.json`
- **Config**: `hosts/m3-atlas/services/traefik.nix`

### Service Integration Template
```nix
services.traefik.dynamicConfigOptions.http = {
  services.<name>.loadBalancer.servers = [{ url = "http://127.0.0.1:<port>"; }];
  routers.<name> = {
    rule = "Host(`<subdomain>.m3ta.dev`)";
    service = "<name>";
    tls.certResolver = "godaddy";
  };
};
```

### Container Pattern
- **Network**: `--network=web --ip=10.89.0.<sequential>`
- **Ports**: Bind localhost only (`127.0.0.1:<external>:<internal>`)
- **Database access**: `--add-host=mysql:10.89.0.1` (gateway IP)

## HOST ROLES

| Host | Type | Hardware | Purpose |
|------|------|----------|---------|
| m3-atlas | Server | x86_64, disko | 20+ services, Traefik hub, PostgreSQL, MySQL |
| m3-helios | Server | x86_64, disko | AdGuard DNS, internal routing |
| m3-ares | Desktop | NVIDIA, Btrfs | Personal workstation, n8n, PostgreSQL |
| m3-kratos | Desktop | AMD, ZFS | Workstation, mem0, PostgreSQL |
| m3-aether | Cloud | QEMU | General purpose VM |
| m3-daedalus | Laptop | home-only | Portable (no full NixOS config) |

## ANTI-PATTERNS (THIS PROJECT)

- **DON'T** add secrets to `secrets/` without updating `secrets.nix` public keys
- **DON'T** hardcode ports - use `config.m3ta.ports.get` or add to registry
- **DON'T** create containers outside the `web` network on m3-atlas
- **DON'T** skip Traefik config for public-facing services on m3-atlas
- **DON'T** bypass extraServices flags - use `hosts/common/extraServices/` pattern
- **DON'T** commit unencrypted secrets or test with real credentials

## UNIQUE TO THIS CONFIG

- **Custom m3ta-nixpkgs**: Local overlay for unreleased/patched packages
- **extraServices abstraction**: Boolean flags to toggle Podman, Ollama, virtualisation per host
- **Mythological naming**: All hosts named after Greek mythology
- **Dual domain strategy**: New services on `m3ta.dev`, legacy redirects from `m3tam3re.com`
- **Per-host nixpkgs versions**: Different hosts can use different nixpkgs commits via specialArgs
- **Container IP registry**: Static IP assignments in 10.89.0.0/24 subnet for predictable networking

## NOTES

- m3-atlas is the service hub - most complex configuration
- Secrets require host SSH keys defined in `secrets.nix` before `agenix -e` works
- Fish and Nushell both configured - choose per-user with shell aliases
- Color scheme (Dracula) applied via nix-colors across all visual tools
- See subdirectory AGENTS.md for deep dives on containers, desktop features, CLI tools
