248 lines
6.8 KiB
Markdown
248 lines
6.8 KiB
Markdown
# 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
|
|
|
|
```bash
|
|
# 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:
|
|
```bash
|
|
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:
|
|
```nix
|
|
{
|
|
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:
|
|
```nix
|
|
{
|
|
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
|
|
|
|
```nix
|
|
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:
|
|
```bash
|
|
agenix -e secrets/my-secret.age
|
|
```
|
|
|
|
2. Register in `secrets.nix`:
|
|
```nix
|
|
"secrets/my-secret.age".publicKeys = systems ++ users;
|
|
```
|
|
|
|
3. Declare in host's `secrets.nix`:
|
|
```nix
|
|
age.secrets.my-secret = {
|
|
file = ../../secrets/my-secret.age;
|
|
owner = "service-user"; # Optional
|
|
mode = "644"; # Optional
|
|
};
|
|
```
|
|
|
|
4. Reference in config:
|
|
```nix
|
|
environmentFiles = [config.age.secrets.my-secret.path];
|
|
```
|
|
|
|
## Container Services Pattern
|
|
|
|
OCI containers via podman:
|
|
```nix
|
|
{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:
|
|
```nix
|
|
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:
|
|
```nix
|
|
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
|