133 lines
3.5 KiB
Markdown
133 lines
3.5 KiB
Markdown
---
|
|
name: nix-module
|
|
description: 'Create or update a NixOS or Home Manager module following Nix-Vibe conventions. Use when adding a new service, desktop app, hardware support, or shared configuration module. Use when the user asks to add a package, service, or application module.'
|
|
argument-hint: '<module-name> [service|desktop|hardware|core]'
|
|
---
|
|
|
|
# Nix Module Creation
|
|
|
|
## When to Use
|
|
- Adding a new service (e.g., a new containerized app, daemon, or web service)
|
|
- Adding a new desktop application module
|
|
- Adding hardware support (e.g., new device driver, firmware)
|
|
- Creating a new shared core module
|
|
- The user asks to "add support for X" or "create a module for X"
|
|
|
|
## Module Pattern
|
|
|
|
All service/feature modules MUST follow this pattern:
|
|
|
|
```nix
|
|
{ config, pkgs, lib, ... }:
|
|
|
|
{
|
|
options.services.<name> = {
|
|
enable = lib.mkEnableOption "description of the service";
|
|
# Additional options as needed
|
|
};
|
|
|
|
config = lib.mkIf config.services.<name>.enable {
|
|
# Configuration here
|
|
};
|
|
}
|
|
```
|
|
|
|
Reference implementation: [modules/services/immich.nix](../../modules/services/immich.nix)
|
|
|
|
## Procedure
|
|
|
|
### 1. Determine Module Type
|
|
|
|
| Type | Directory | Example |
|
|
|------|-----------|---------|
|
|
| Service (daemon, container, webapp) | `modules/services/` | immich, jellyfin, ntfy |
|
|
| Desktop app | `modules/desktop/apps/` | soundux, opencode, freeshow |
|
|
| Desktop environment | `modules/desktop/` | gnome.nix, gui.nix |
|
|
| Hardware support | `modules/hardware/` | fingerprint.nix |
|
|
| Core system config | `modules/core/` | common.nix, settings.nix, fonts.nix |
|
|
|
|
### 2. Create the Module File
|
|
|
|
#### Service Module Template
|
|
```nix
|
|
{ config, pkgs, lib, ... }:
|
|
|
|
{
|
|
options.services.<service-name> = {
|
|
enable = lib.mkEnableOption "<Service Description>";
|
|
port = lib.mkOption {
|
|
type = lib.types.port;
|
|
default = <default-port>;
|
|
description = "Port for <service>";
|
|
};
|
|
# Add data directories, user config, etc. as needed
|
|
};
|
|
|
|
config = lib.mkIf config.services.<service-name>.enable {
|
|
# Service-specific configuration
|
|
|
|
# For stateful services, ensure data directories exist
|
|
systemd.tmpfiles.rules = [
|
|
"d /var/lib/<service> 0700 <user> <group> -"
|
|
];
|
|
|
|
# Open firewall if needed
|
|
networking.firewall.allowedTCPPorts = [ config.services.<service-name>.port ];
|
|
};
|
|
}
|
|
```
|
|
|
|
#### Desktop App Module Template
|
|
```nix
|
|
{ pkgs, ... }:
|
|
|
|
{
|
|
environment.systemPackages = with pkgs; [
|
|
<package-name>
|
|
];
|
|
}
|
|
```
|
|
|
|
### 3. Register in Host Configuration
|
|
|
|
Import the module in the target host's `configuration.nix`:
|
|
```nix
|
|
imports = [
|
|
# ...existing imports...
|
|
../../modules/services/<module-name>.nix
|
|
];
|
|
```
|
|
|
|
Then enable it:
|
|
```nix
|
|
services.<service-name>.enable = true;
|
|
```
|
|
|
|
### 4. Update README.md
|
|
Add the new software to the Software Inventory table with the appropriate host columns.
|
|
|
|
### 5. Validate
|
|
Run the full validation workflow. See [nix-flake-rebuild](../nix-flake-rebuild/SKILL.md).
|
|
|
|
## Key Conventions
|
|
|
|
### Secrets
|
|
Never hardcode secrets. Use SOPS:
|
|
```nix
|
|
sops.secrets."<host>/<secret-name>" = {
|
|
owner = "<user>";
|
|
group = "users";
|
|
mode = "0440";
|
|
};
|
|
```
|
|
See [docs/sops-secrets.md](../../docs/sops-secrets.md) for details.
|
|
|
|
### Overlay Awareness
|
|
- If a package needs NVIDIA/CUDA or NDI, it should only be added to `x1carbon` (the only host using the full `overlays` set)
|
|
- Desktops/laptops use `desktopOverlays` (`stable` without CUDA); servers use `serverOverlays`
|
|
|
|
### Module Composition
|
|
- Core modules (`modules/core/common.nix`) apply to ALL hosts
|
|
- Desktop modules only apply to GUI hosts
|
|
- Service modules are imported per-host as needed
|