6.3 KiB
6.3 KiB
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>.ageafter adding keys tosecrets.nix - Reference:
config.age.secrets.<name>.pathin 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
webnetwork (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 = truein 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
# 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
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 updatingsecrets.nixpublic keys - DON'T hardcode ports - use
config.m3ta.ports.getor add to registry - DON'T create containers outside the
webnetwork 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 fromm3tam3re.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.nixbeforeagenix -eworks - 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