Skip to content

Modules

The framework’s features are provided as high-level NixOS modules, grouped by category under dnf/modules/ and documented in the module reference.

  • standard : system, console, graphic, service, admin, user.
  • mixin : macro-modules composing host profiles and user profile add-ons.
  • home : Home Manager 🡕 modules and profiles.
  1. Choose the category (dnf/modules/standard/<category>/ or mixin).
  2. Write the file header according to the rules (see code headers).
  3. Declare the options then the module config.
  4. Regenerate (just generate) and test before committing.

For a self-hosted service (web UI, API, storage…), follow the dedicated guide Create a service module : reverse proxy, persistence, firewall, Kanidm SSO and per-host activation.

A DNF module follows the classic NixOS pattern: a header, an options block and a config block activated by enable.

dnf/modules/standard/service/hello.nix
{ lib, config, ... }:
let
cfg = config.darkone.service.hello;
in
{
options.darkone.service.hello = {
enable = lib.mkEnableOption "Enable the hello service";
port = lib.mkOption {
type = lib.types.port;
default = 8080;
description = "Listening port.";
};
};
config = lib.mkIf cfg.enable {
# ... actual configuration, only activated if enable = true
};
}

All framework options live under the darkone namespace :

darkone.<category>.<name>.<option>
  • darkone.service.immich.enable : a service.
  • darkone.system.security.level : a system setting.
  • darkone.host.desktop.enable : a host profile (mixin).

dnfLib (defined in dnf/lib/) provides cross-cutting functions, injected into each module. The most useful ones:

HelperRole
extractServiceParams / buildServiceParamsRead service parameters (domain, title, icon…).
mkOidcContext / mkKanidmEndpointsConnect a service to Kanidm SSO (OIDC).
mkInternalFirewallOpen ports on the internal interface only.
findHost / findService / isGateway / isHcsQuery network topology.
mkHomepageSectionDeclare the portal entry.
mkIsActiveActivate a security rule based on level/category.

A service declares its topology in dnf/config/modules.nix (not in its .nix) : reverse proxy, uniqueness per zone, external access, automatic activation by host profile.

dnf/config/modules.nix
adguardhome = {
uniquePerZone = true;
activation.profiles.gateway.triggers.keys.adguardhome = [ "enable" ];
};
FlagDefaultEffect
reverseProxytrueThe service is exposed via Caddy.
uniquePerZonefalseOnly one instance allowed per zone.
externalAccessfalseReachable outside the zone (via the HCS).
require[ ]Services to enable on the same host (otherwise build error).
activation.profiles.<profile>Enabled by default on hosts of a profile.

Each module folder has a default.nix that imports its files. It is generated by just generate (list of imports) → do not edit it.

Fenêtre de terminal
just generate # regenerates default.nix + var/generated/