# Custom Modules

This directory contains documentation for the custom modules used in this NixOS configuration.

## Overview

Modules are split into three categories:

- **NixOS modules** (`modules/nixos/`) — system-level configuration
- **Home Manager modules** (`modules/home/`) — user-level configuration
- **Darwin modules** (`modules/darwin/`) — macOS-specific configuration

All modules are auto-discovered by Snowfall Lib and expose options under the `mjallen` namespace.

## NixOS Modules

### Boot (`modules/nixos/boot/`)

| Module | Description |
|---|---|
| `boot/common/` | Shared boot defaults (quiet boot, Plymouth) |
| `boot/lanzaboote/` | Secure Boot via Lanzaboote |
| `boot/systemd-boot/` | systemd-boot (non-secure-boot systems) |
| `boot/plymouth/` | Plymouth splash screen |

### Desktop (`modules/nixos/desktop/`)

| Module | Description |
|---|---|
| `desktop/gnome/` | GNOME desktop environment |
| `desktop/hyprland/` | Hyprland compositor |
| `desktop/cosmic/` | COSMIC desktop environment |

### Development (`modules/nixos/development/`)

Enables development tools and language support. Options:

```nix
mjallen.development = {
  enable           = true;
  includeLanguages = [ "python" "c" ];
  includeContainers = true;
};
```

### Hardware (`modules/nixos/hardware/`)

| Module | Description |
|---|---|
| `hardware/amd/` | AMD GPU (AMDGPU driver, LACT) |
| `hardware/nvidia/` | NVIDIA GPU |
| `hardware/battery/` | Battery charge threshold management |
| `hardware/raspberry-pi/` | Raspberry Pi hardware support and DT overlays |
| `hardware/openrgb/` | OpenRGB for LED control |
| `hardware/btrfs/` | btrfs-specific settings |
| `hardware/common/` | Common hardware defaults |

### Headless (`modules/nixos/headless/`)

Server profile — disables suspend/hibernate, enables systemd watchdog, no display manager.

```nix
mjallen.headless.enable = true;
```

### Home Assistant (`modules/nixos/homeassistant/`)

Full smart home stack. See [Home Assistant docs](../home-assistant/README.md) for details.

```nix
mjallen.services.home-assistant.enable = true;
```

### Impermanence (`modules/nixos/impermanence/`)

Ephemeral root filesystem with explicit persistence declarations.

```nix
mjallen.impermanence = {
  enable           = true;
  extraDirectories = [ { directory = "/var/lib/myapp"; user = "myapp"; } ];
};
```

### Monitoring (`modules/nixos/monitoring/`)

Prometheus metrics and Grafana dashboards.

```nix
mjallen.monitoring.enable = true;
```

### Network (`modules/nixos/network/`)

Hostname, firewall, NetworkManager profiles, static IP configuration.

```nix
mjallen.network = {
  hostName = "my-host";
  ipv4 = {
    method    = "manual";
    address   = "10.0.1.5/24";
    gateway   = "10.0.1.1";
    dns       = "1.1.1.1";
    interface = "eth0";
  };
  firewall = {
    enable          = true;
    allowedTCPPorts = [ 80 443 ];
  };
};
```

### Power (`modules/nixos/power/`)

UPS (NUT) support.

```nix
mjallen.power.ups.enable = true;
```

### Security (`modules/nixos/security/`)

| Module | Description |
|---|---|
| `security/common/` | Common hardening (kernel params, etc.) |
| `security/tpm/` | TPM2 — Clevis disk unlock |

### Services (`modules/nixos/services/`)

~50 self-hosted service modules, all built with `mkModule`. Each exposes at minimum `enable`, `port`, `reverseProxy`, and `openFirewall`. Common usage pattern:

```nix
mjallen.services.jellyfin = {
  enable         = true;
  port           = 8096;
  reverseProxy.enable = true;
};
```

Available services:

`actual`, `ai`, `appimage`, `arrs`, `attic`, `authentik`, `authentikRac`, `booklore`, `caddy`, `calibre`, `calibre-web`, `cockpit`, `code-server`, `collabora`, `coturn`, `crowdsec`, `dispatcharr`, `free-games-claimer`, `gitea`, `glance`, `glances`, `grafana`, `guacd`, `headscale`, `immich`, `jellyfin`, `seerr`, `lubelogger`, `manyfold`, `matrix`, `minecraft`, `mongodb`, `nebula`, `netbootxyz`, `nextcloud`, `ntfy`, `onlyoffice`, `opencloud`, `orca`, `paperless`, `paperless-ai`, `protonmail-bridge`, `restic`, `samba`, `sparky-fitness`, `sparky-fitness-server`, `sunshine`, `tdarr`, `termix`, `tunarr`, `unmanic`, `uptime-kuma`, `wyoming`, `your-spotify`

#### Nebula VPN (`services/nebula/`)

Unified module for both lighthouse and node roles:

```nix
# Lighthouse
mjallen.services.nebula = {
  enable         = true;
  isLighthouse   = true;
  port           = 4242;
  secretsPrefix  = "pi5/nebula";
  secretsFile    = lib.snowfall.fs.get-file "secrets/pi5-secrets.yaml";
  hostSecretName = "lighthouse";
};

# Node
mjallen.services.nebula = {
  enable         = true;
  port           = 4242;
  lighthouses    = [ "10.1.1.1" ];
  staticHostMap  = { "10.1.1.1" = [ "mjallen.dev:4242" ]; };
  secretsPrefix  = "mymachine/nebula";
  secretsFile    = lib.snowfall.fs.get-file "secrets/mymachine-secrets.yaml";
  hostSecretName = "mymachine";
};
```

See [Secrets Management](../../README.md#generating-nebula-vpn-certificates) for how to generate the required certificates.

### SOPS (`modules/nixos/sops/`)

Configures sops-nix to decrypt secrets using the machine's SSH host key as an age key.

```nix
mjallen.sops = {
  enable       = true;
  sshKeyPaths  = [ "/etc/ssh/ssh_host_ed25519_key" ];  # default
};
```

### User (`modules/nixos/user/`)

System user account management.

```nix
mjallen.user = {
  name         = "matt";
  mutableUsers = false;
  extraGroups  = [ "docker" "video" ];
};
```

---

## Home Manager Modules

### Desktop

| Module | Description |
|---|---|
| `desktop/gnome/` | GNOME user settings (extensions, keybindings, etc.) |
| `desktop/theme/` | Theme configuration |

### Programs

| Module | Description |
|---|---|
| `programs/btop/` | btop system monitor |
| `programs/code/` | VS Code / VSCodium settings |
| `programs/git/` | Git user config |
| `programs/hyprland/` | Hyprland compositor config |
| `programs/kitty/` | Kitty terminal config |
| `programs/librewolf/` | LibreWolf browser settings |
| `programs/mako/` | Mako notification daemon |
| `programs/nwg-dock/` | nwg-dock panel |
| `programs/nwg-drawer/` | nwg-drawer app launcher |
| `programs/nwg-panel/` | nwg-panel bar |
| `programs/opencode/` | OpenCode AI coding assistant |
| `programs/update-checker/` | Automatic flake update checker |
| `programs/waybar/` | Waybar status bar |
| `programs/wlogout/` | Logout menu |
| `programs/wofi/` | Wofi launcher |
| `programs/zsh/` | Zsh shell config |

### Other

| Module | Description |
|---|---|
| `gpg/` | GPG agent configuration |
| `services/pass/` | Password store |
| `shell-aliases/` | Common shell aliases |
| `sops/` | User-level SOPS secrets |
| `stylix/` | System-wide theming (colours, fonts, wallpaper) |
| `user/` | User environment defaults |

---

## Module Development

### Using `mkModule`

The `lib.mjallen.mkModule` helper (`lib/module/default.nix`) creates a fully-featured NixOS module from a minimal spec:

```nix
{ config, lib, namespace, pkgs, ... }:
let
  name = "my-service";
  cfg  = config.${namespace}.services.${name};

  serviceConfig = lib.${namespace}.mkModule {
    inherit config name;
    description = "my service";
    options = {
      # extra options beyond the standard set
      myOption = lib.${namespace}.mkOpt lib.types.str "default" "Description";
    };
    moduleConfig = {
      services.my-service = {
        enable = true;
        port   = cfg.port;
      };
    };
  };
in
{ imports = [ serviceConfig ]; }
```

Standard options provided by `mkModule` for free: `enable`, `port`, `listenAddress`, `openFirewall`, `configDir`, `dataDir`, `createUser`, `configureDb`, `environmentFile`, `reverseProxy.*`, `redis.*`, `extraEnvironment`, `hashedPassword`, `puid`, `pgid`, `timeZone`.

### Using `mkContainerService`

For Podman/OCI container services, use `mkContainerService` instead:

```nix
lib.${namespace}.mkContainerService {
  inherit config name;
  image        = "ghcr.io/example/my-app:latest";
  internalPort = 8080;
  volumes      = [ "${cfg.configDir}:/config" ];
};
```

### Option helpers

```nix
lib.mjallen.mkOpt      types.str "default" "description"
lib.mjallen.mkBoolOpt  false "description"
lib.mjallen.mkOpt'     types.int 80        # no description
lib.mjallen.enabled                         # { enable = true; }
lib.mjallen.disabled                        # { enable = false; }
```
