Files
nixos-config/AGENTS.md
2025-12-28 11:28:19 +01:00

6.8 KiB

AGENTS.md - NixOS Configuration Repository

This document provides guidelines for AI agents working on this NixOS flake configuration.

Repository Overview

Multi-host NixOS flake managing servers and workstations with home-manager integration.

  • Hosts: m3-aether, m3-ares, m3-atlas, m3-helios, m3-kratos
  • User: m3tam3re
  • Key inputs: nixpkgs (unstable), home-manager, agenix, disko, nix-colors

Build/Rebuild Commands

# NixOS system rebuild
sudo nixos-rebuild switch --flake .#<hostname>
sudo nixos-rebuild switch --flake .#m3-atlas

# Home-manager rebuild
home-manager --flake . switch
home-manager --flake .#m3tam3re@m3-daedalus switch

# Flake operations
nix flake check                    # Validate flake
nix flake update                   # Update all inputs
nix flake lock --update-input <name>  # Update single input

# Development shell
nix develop .#infraShell           # OpenTofu + nixos-anywhere

# Format Nix files
alejandra .                        # Format all .nix files
alejandra <file.nix>               # Format single file

Testing

No formal test suite. Verification is done via:

nix flake check                    # Syntax and evaluation check
nix build .#nixosConfigurations.<host>.config.system.build.toplevel --dry-run

Directory Structure

.
├── flake.nix              # Flake definition with all hosts
├── secrets.nix            # Agenix public key mappings
├── home/
│   ├── common/            # Shared home-manager config (overlays, nix settings)
│   ├── features/          # Modular features
│   │   ├── cli/           # Shell tools (fish, nushell, starship, zellij)
│   │   ├── coding/        # Development tools
│   │   └── desktop/       # GUI apps, Hyprland, theming
│   └── m3tam3re/          # Per-host user configs
├── hosts/
│   ├── common/            # Shared NixOS config
│   │   ├── extraServices/ # Toggle-able services (ollama, podman, flatpak)
│   │   ├── users/         # User definitions
│   │   └── ports.nix      # Port allocations
│   └── m3-*/              # Host-specific configs
│       ├── default.nix    # Entry point (imports common + host modules)
│       ├── configuration.nix  # Core system config
│       ├── hardware-configuration.nix
│       ├── programs.nix   # Host-specific programs
│       ├── secrets.nix    # Agenix secret declarations
│       └── services/      # Service configurations
│           └── containers/ # OCI container definitions
├── modules/               # Custom NixOS/home-manager modules
├── overlays/              # Nixpkgs overlays (stable, locked, pinned, master)
├── pkgs/                  # Custom package definitions
└── secrets/               # Encrypted .age files

Code Style Guidelines

Module Pattern

Standard Nix module structure:

{
  config,
  lib,
  pkgs,
  ...
}: {
  imports = [
    ./submodule.nix
  ];

  # Configuration here
}

Formatting

  • Formatter: Use alejandra (included in CLI packages)
  • Indentation: 2 spaces
  • Line length: No strict limit, but keep readable
  • Trailing commas: Required in lists and attrsets
  • Semicolons: Required after each attribute

Naming Conventions

Type Convention Example
Files lowercase, hyphenated hardware-configuration.nix
Hosts m3-<name> m3-atlas, m3-kratos
Options camelCase path extraServices.ollama.enable
Feature flags features.<category>.<name>.enable features.cli.nushell.enable
Secrets <service>-env.age or descriptive n8n-env.age, wg-DE.age

Option Definitions

Use lib functions for custom options:

{
  config,
  lib,
  pkgs,
  ...
}:
with lib; let
  cfg = config.features.cli.myFeature;
in {
  options.features.cli.myFeature.enable = mkEnableOption "enable myFeature";

  config = mkIf cfg.enable {
    # Configuration when enabled
  };
}

Imports

  • Import order: inputs/modules first, then local files
  • Use relative paths: ./subdir or ../common
  • Group related imports together

Package Lists

home.packages = with pkgs; [
  package1
  package2
  # Commented packages for reference
  # disabled-package
];

Secrets Management

Uses agenix for encrypted secrets.

Adding a New Secret

  1. Create the secret file:

    agenix -e secrets/my-secret.age
    
  2. Register in secrets.nix:

    "secrets/my-secret.age".publicKeys = systems ++ users;
    
  3. Declare in host's secrets.nix:

    age.secrets.my-secret = {
      file = ../../secrets/my-secret.age;
      owner = "service-user";  # Optional
      mode = "644";            # Optional
    };
    
  4. Reference in config:

    environmentFiles = [config.age.secrets.my-secret.path];
    

Container Services Pattern

OCI containers via podman:

{config, ...}: {
  virtualisation.oci-containers.containers."service-name" = {
    image = "registry/image:tag";
    environmentFiles = [config.age.secrets.service-env.path];
    ports = ["127.0.0.1:8080:8080"];
    volumes = ["service_data:/data"];
    extraOptions = ["--network=web"];
  };

  # Traefik routing
  services.traefik.dynamicConfigOptions.http = {
    services.service-name.loadBalancer.servers = [
      { url = "http://localhost:8080/"; }
    ];
    routers.service-name = {
      rule = "Host(`service.domain.com`)";
      tls.certResolver = "godaddy";
      service = "service-name";
      entrypoints = "websecure";
    };
  };
}

Theming

Uses nix-colors with Dracula scheme:

colorScheme = inputs.nix-colors.colorSchemes.dracula;

# Reference colors
"#${config.colorScheme.palette.base00}"  # Background
"#${config.colorScheme.palette.base05}"  # Foreground

Overlays

Custom overlays in overlays/default.nix:

  • stable-packages: nixpkgs-stable as pkgs.stable.*
  • locked-packages: Pinned nixpkgs as pkgs.locked.*
  • master-packages: nixpkgs-master as pkgs.master.*

Use when you need a specific package version:

home.packages = [ pkgs.stable.somePackage ];

Common Pitfalls

  1. Missing imports: Ensure new files are imported in parent default.nix
  2. Secret paths: Use config.age.secrets.<name>.path, not hardcoded paths
  3. Rebuild required: Changes need nixos-rebuild or home-manager switch
  4. Overlay scope: Overlays must be added to both home/common and hosts/common
  5. Port conflicts: Check hosts/common/ports.nix before allocating new ports

Commit Style

Short, descriptive messages:

  • flake update - Dependency updates
  • +package - Adding new package
  • service-name: description - Service changes
  • host: description - Host-specific changes