Files
dev/configs/nixos/guests/navidrome.nix

141 lines
3.8 KiB
Nix

{
config,
lib,
...
}:
let
cfg = config.guests.navidrome;
envFile = "/run/secrets/navidrome.env";
hasLastfmSecrets = cfg.lastfmApiKeySecret != null && cfg.lastfmSecretSecret != null;
hostSecrets = ../secrets + "/${config.networking.hostName}.yaml";
in
{
options.guests.navidrome = {
dataPath = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = "/srv/navidrome";
description = "Host path bind-mounted as Navidrome's state directory.";
};
musicPath = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = "/srv/music";
description = "Host path bind-mounted as Navidrome's music directory.";
};
dataDir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/navidrome";
description = "Guest path where Navidrome stores state.";
};
musicDir = lib.mkOption {
type = lib.types.str;
default = "/music";
description = "Guest path where Navidrome reads the music library.";
};
port = lib.mkOption {
type = lib.types.port;
default = 4533;
description = "Port Navidrome listens on.";
};
enableSharing = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Enables Navidrome sharing support.";
};
settings = lib.mkOption {
type = lib.types.attrs;
default = { };
description = "Additional non-secret Navidrome settings.";
};
lastfmApiKeySecret = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = "services/navidrome/lastfm/api-key";
description = "SOPS secret name containing the Navidrome Last.fm API key.";
};
lastfmSecretSecret = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = "services/navidrome/lastfm/secret";
description = "SOPS secret name containing the Navidrome Last.fm secret.";
};
};
config = lib.mkIf cfg.enable {
assertions = [
{
assertion = cfg.dataPath != null;
message = "guests.navidrome.dataPath must point at the host directory that stores Navidrome state.";
}
{
assertion = cfg.musicPath != null;
message = "guests.navidrome.musicPath must point at the host directory that stores the music library.";
}
];
guests.navidrome = {
interior.modules.services.navidrome = {
enable = true;
inherit (cfg)
dataDir
musicDir
port
enableSharing
settings
;
environmentFile = if hasLastfmSecrets then envFile else null;
};
mounts =
{
${cfg.dataDir} = {
directory = cfg.dataPath;
owner = config.registry."stable-uid".${config.networking.hostName}.navidrome;
group = "storage";
mode = "2770";
};
${cfg.musicDir} = {
directory = cfg.musicPath;
owner = "root";
group = "storage";
mode = "2770";
};
}
// lib.optionalAttrs hasLastfmSecrets {
${envFile} = {
file = config.sops.templates."navidrome.env".path;
readOnly = true;
};
};
limits = {
memory = lib.mkDefault "2G";
cpu = lib.mkDefault "200%";
tasksMax = lib.mkDefault 512;
};
};
sops.secrets = lib.optionalAttrs hasLastfmSecrets {
${cfg.lastfmApiKeySecret}.sopsFile = hostSecrets;
${cfg.lastfmSecretSecret}.sopsFile = hostSecrets;
};
sops.templates."navidrome.env" = lib.mkIf hasLastfmSecrets {
owner = "root";
group = "storage";
mode = "0440";
content = ''
ND_LASTFM_APIKEY=${config.sops.placeholder.${cfg.lastfmApiKeySecret}}
ND_LASTFM_SECRET=${config.sops.placeholder.${cfg.lastfmSecretSecret}}
'';
};
};
}