Files
nixos-config/AGENTS.md
m3tm3re 047b60a6a8 refactor: update Pi agent configuration and devShell
- Switch model provider from zai/glm-5.1 to minimax/MiniMax-M2.7
- Add coding rules for Nix language and standard concerns
- Add linting tools (statix, deadnix) to devShell
- Simplify devShell configuration
- Update AGENTS.md project rules
2026-04-22 17:59:23 +02:00

9.8 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>.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

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

{ 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

# Format (alejandra)
nix fmt

# Lint (statix, deadnix - only in dev shell)
nix develop
statix check .
deadnix .

# Validate flake
nix flake check

Commit Conventions

Format: <type>: <brief description>

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

# 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 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