# 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//` | 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/.age` after adding keys to `secrets.nix` - **Reference**: `config.age.secrets..path` in service configs - **Pattern**: Service env files use `environmentFiles = [config.age.secrets.-env.path]` ### Service Organization - **Native services**: `hosts//services/.nix` - **Containers**: `hosts//services/containers/.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...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/.age # Infrastructure shell (OpenTofu) nix develop .#infraShell # Check configuration (no activation) nixos-rebuild dry-build --flake .# ``` ## 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..loadBalancer.servers = [{ url = "http://127.0.0.1:"; }]; routers. = { rule = "Host(`.m3ta.dev`)"; service = ""; tls.certResolver = "godaddy"; }; }; ``` ### Container Pattern - **Network**: `--network=web --ip=10.89.0.` - **Ports**: Bind localhost only (`127.0.0.1::`) - **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