# 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` ## CODING RULES This project uses coding rules from the AGENTS repository (`inputs.agents`) plus project-specific conventions. ### Standard Rules (AGENTS repo) | Rule | Source | Purpose | |------|--------|---------| | `languages/nix.md` | AGENTS/rules/ | Nix language conventions, flake patterns | | `concerns/coding-style.md` | AGENTS/rules/ | General coding principles | | `concerns/naming.md` | AGENTS/rules/ | Naming conventions per language | | `concerns/documentation.md` | AGENTS/rules/ | Documentation standards | | `concerns/testing.md` | AGENTS/rules/ | Testing guidelines | | `concerns/git-workflow.md` | AGENTS/rules/ | Commit message format, branch naming | | `concerns/project-structure.md` | AGENTS/rules/ | Project layout conventions | ### NixOS-Config Specific Rules #### Project Structure ``` nixos-config/ ├── flake.nix # Entry point ├── hosts/ # Host-specific NixOS configs │ ├── common/ # Shared: ports, users, base config │ ├── m3-atlas/ # Server with Traefik hub │ ├── m3-helios/ # AdGuard DNS │ ├── m3-ares/ # Desktop (NVIDIA) │ └── m3-kratos/ # Desktop (AMD) ├── home/ # Home-manager configs │ ├── common/ # Shared home config │ ├── features/ # Feature modules (cli, desktop, coding) │ └── m3tam3re/ # User-specific configs ├── modules/ # Custom NixOS/HM modules ├── overlays/ # Package overlays ├── pkgs/ # Custom packages └── secrets/ # Agenix encrypted secrets ``` #### Naming Conventions | Type | Convention | Example | |------|------------|---------| | Hosts | mythological-names | `m3-atlas`, `m3-helios` | | Files | hyphen-case | `my-service.nix` | | Variables | camelCase | `portHelpers`, `serviceConfig` | | Options | m3ta.* | `config.m3ta.ports.get` | | Packages | lowercase-hyphen | `hyprpaper-random` | #### Nix Module Pattern ```nix { config, lib, pkgs, ... }: with lib; let cfg = config.m3ta.myModule; in { options.m3ta.myModule = { enable = mkEnableOption "my module"; }; config = mkIf cfg.enable { # Configuration here }; } ``` #### Anti-Patterns (Never Do) | Don't | Do Instead | |-------|------------| | Hardcode ports | `config.m3ta.ports.get "service"` | | Skip secrets.nix update | Add keys first, then `agenix -e` | | Containers outside web network | `--network=web --ip=10.89.0.N` | | Skip Traefik for public services | Configure dynamic config | | Bypass extraServices flags | Use feature flags properly | | Use `fetchTarball` | Use flake inputs | | Use `with pkgs;` in modules | Explicit `pkgs.package` | ### Formatting & Linting ```bash # Format (alejandra) nix fmt # Lint (statix, deadnix - only in dev shell) nix develop statix check . deadnix . # Validate flake nix flake check ``` ### Commit Conventions Format: `: ` Types: `feat`, `fix`, `docs`, `style`, `refactor`, `chore` Examples: - `feat: add new host m3-hermes` - `fix: resolve port conflict in mem0 module` - `docs: update AGENTS.md with new service` - `style: format nix files` - `refactor: simplify port management` - `chore: update nixpkgs inputs` ### Tools in Dev Shell | Tool | Purpose | |------|---------| | `alejandra` | Nix code formatter | | `nixd` | Nix language server | | `statix` | Nix linter | | `deadnix` | Find dead code | | `agenix` | Secret management | ## 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