From 8569c4018398253e11e7dae0496df4d008c225c8 Mon Sep 17 00:00:00 2001 From: soraefir Date: Sun, 7 Jun 2026 16:21:21 +0200 Subject: [PATCH] fix --- modules/server/containers/apps/.template.nix | 2 +- modules/server/containers/apps/authentik.nix | 10 ++-- modules/server/containers/apps/calibre.nix | 4 +- modules/server/containers/apps/ethercalc.nix | 4 +- modules/server/containers/apps/etherpad.nix | 8 +-- modules/server/containers/apps/favicon.nix | 4 +- modules/server/containers/apps/freshrss.nix | 4 +- modules/server/containers/apps/frigate.nix | 10 ++-- modules/server/containers/apps/gitea.nix | 8 +-- modules/server/containers/apps/handbrake.nix | 10 ++-- modules/server/containers/apps/immich.nix | 14 +++--- modules/server/containers/apps/influx.nix | 18 +++---- modules/server/containers/apps/invidious.nix | 6 +-- modules/server/containers/apps/jellyfin.nix | 8 +-- modules/server/containers/apps/nextcloud.nix | 6 +-- modules/server/containers/apps/openhab.nix | 12 ++--- modules/server/containers/apps/selfmark.nix | 8 +-- modules/server/containers/apps/servarr.nix | 22 ++++---- modules/server/containers/apps/suwayomi.nix | 4 +- modules/server/containers/apps/traefik.nix | 6 +-- .../server/containers/apps/transmission.nix | 10 ++-- modules/server/containers/apps/umami.nix | 2 +- modules/server/containers/default.nix | 7 ++- modules/shared/syscfg/server.nix | 50 +++++++++++++------ 24 files changed, 129 insertions(+), 108 deletions(-) diff --git a/modules/server/containers/apps/.template.nix b/modules/server/containers/apps/.template.nix index 1b65606..4d32cfb 100644 --- a/modules/server/containers/apps/.template.nix +++ b/modules/server/containers/apps/.template.nix @@ -24,7 +24,7 @@ in { runtime = { paths = [{ - path="${serverCfg.path.config}/example/"; + path="${serverCfg.path.config.path}/example/"; mode = "0444"; }]; diff --git a/modules/server/containers/apps/authentik.nix b/modules/server/containers/apps/authentik.nix index 1755ead..dfa67ef 100644 --- a/modules/server/containers/apps/authentik.nix +++ b/modules/server/containers/apps/authentik.nix @@ -35,7 +35,7 @@ in { runtime = { paths = [{ - path="${serverCfg.path.config}/authentik"; + path="${serverCfg.path.config.path}/authentik"; owner = "1000:1000"; dirs = ["media" "templates"]; mode = "0755"; @@ -69,8 +69,8 @@ in { cmd = [ "server" ]; volumes = [ - "${serverCfg.path.config}/authentik/media:/media" - "${serverCfg.path.config}/authentik/templates:/templates" + "${serverCfg.path.config.path}/authentik/media:/media" + "${serverCfg.path.config.path}/authentik/templates:/templates" "${authentikData}:/blueprints/custom:ro" "${mediaCfg.logo.svg}:${logoSvgMount}:ro" "${mediaCfg.logo.ico}:${logoIcoMount}:ro" @@ -94,8 +94,8 @@ in { overrides = { cmd = [ "worker" ]; volumes = [ - "${serverCfg.path.config}/authentik/media:/media" - "${serverCfg.path.config}/authentik/templates:/templates" + "${serverCfg.path.config.path}/authentik/media:/media" + "${serverCfg.path.config.path}/authentik/templates:/templates" "${authentikData}:/blueprints/custom:ro" "${mediaCfg.logo.svg}:${logoSvgMount}:ro" "${mediaCfg.logo.ico}:${logoIcoMount}:ro" diff --git a/modules/server/containers/apps/calibre.nix b/modules/server/containers/apps/calibre.nix index 5925b6e..baff5dd 100644 --- a/modules/server/containers/apps/calibre.nix +++ b/modules/server/containers/apps/calibre.nix @@ -27,8 +27,8 @@ in { }; overrides = { volumes = [ - "${serverCfg.path.book}:/calibre-library" - "${serverCfg.path.download}/book:/cwa-book-ingest" + "${serverCfg.path.book.path}:/calibre-library" + "${serverCfg.path.download.path}/book:/cwa-book-ingest" ]; }; }; diff --git a/modules/server/containers/apps/ethercalc.nix b/modules/server/containers/apps/ethercalc.nix index 83b633a..5805a5a 100644 --- a/modules/server/containers/apps/ethercalc.nix +++ b/modules/server/containers/apps/ethercalc.nix @@ -17,7 +17,7 @@ in { runtime = { paths = [{ - path="${serverCfg.path.data}/ethercalc/"; + path="${serverCfg.path.data.path}/ethercalc/"; mode = "0666"; }]; @@ -33,7 +33,7 @@ in { }; overrides = { volumes = [ - "${serverCfg.path.data}/ethercalc:/data" + "${serverCfg.path.data.path}/ethercalc:/data" ]; }; }; diff --git a/modules/server/containers/apps/etherpad.nix b/modules/server/containers/apps/etherpad.nix index 116ce0b..3faf107 100644 --- a/modules/server/containers/apps/etherpad.nix +++ b/modules/server/containers/apps/etherpad.nix @@ -83,7 +83,7 @@ in { runtime = { paths = [{ - path="${serverCfg.path.config}/etherpad/"; + path="${serverCfg.path.config.path}/etherpad/"; mode = "0444"; }]; @@ -111,7 +111,7 @@ in { cmd = [ "--settings" "/etc/etherpad/settings.json" "--apikey" "/etc/etherpad/APIKEY.txt" ]; volumes = [ "${settings}:/etc/etherpad/settings.json" - "${serverCfg.path.config}/etherpad/APIKEY.txt:/etc/etherpad/APIKEY.txt:ro" + "${serverCfg.path.config.path}/etherpad/APIKEY.txt:/etc/etherpad/APIKEY.txt:ro" ]; }; }; @@ -121,8 +121,8 @@ in { trigger = "server"; envFile = config.sops.secrets."ETHERPAD".path; script = pkgs.writeShellScript "setup" '' - echo "$APIKEY" > ${serverCfg.path.config}/etherpad/APIKEY.txt - chmod 444 ${serverCfg.path.config}/etherpad/APIKEY.txt + echo "$APIKEY" > ${serverCfg.path.config.path}/etherpad/APIKEY.txt + chmod 444 ${serverCfg.path.config.path}/etherpad/APIKEY.txt ''; }; }; diff --git a/modules/server/containers/apps/favicon.nix b/modules/server/containers/apps/favicon.nix index 823d63a..ea18434 100644 --- a/modules/server/containers/apps/favicon.nix +++ b/modules/server/containers/apps/favicon.nix @@ -232,7 +232,7 @@ in { runtime = { paths = [ { - path = "${serverCfg.path.config}/favicon"; + path = "${serverCfg.path.config.path}/favicon"; mode = "0755"; dirs = [ "cache" ]; } @@ -260,7 +260,7 @@ in { overrides = { volumes = [ "${configFile}:/config/config.json:ro" - "${serverCfg.path.config}/favicon/cache:/cache" + "${serverCfg.path.config.path}/favicon/cache:/cache" "${mediaCfg.logo.svg}:${logoSvgMount}:ro" ]; }; diff --git a/modules/server/containers/apps/freshrss.nix b/modules/server/containers/apps/freshrss.nix index 05abd1a..abeca78 100644 --- a/modules/server/containers/apps/freshrss.nix +++ b/modules/server/containers/apps/freshrss.nix @@ -11,7 +11,7 @@ in { runtime = { paths = [ { - path = "${serverCfg.path.config}/freshrss"; + path = "${serverCfg.path.config.path}/freshrss"; owner = "1000:1000"; mode = "0755"; } @@ -37,7 +37,7 @@ in { overrides = { environmentFiles = [ config.sops.secrets."FRESHRSS".path config.sops.secrets."CUSTOM".path ]; - volumes = ["${serverCfg.path.config}/freshrss:/var/www/FreshRSS/data"]; + volumes = ["${serverCfg.path.config.path}/freshrss:/var/www/FreshRSS/data"]; }; }; }; diff --git a/modules/server/containers/apps/frigate.nix b/modules/server/containers/apps/frigate.nix index d1a7fd7..0fe90c5 100644 --- a/modules/server/containers/apps/frigate.nix +++ b/modules/server/containers/apps/frigate.nix @@ -32,7 +32,7 @@ in { runtime = { paths = [ { - path = "${serverCfg.path.config}/frigate/"; + path = "${serverCfg.path.config.path}/frigate/"; mode = "0755"; } { @@ -53,7 +53,7 @@ in { overrides = { cmd = [ ]; volumes = [ - "${serverCfg.path.config}/frigate:/config" + "${serverCfg.path.config.path}/frigate:/config" "/var/lib/frigate/storage:/media/frigate" "/dev/bus/usb:/dev/bus/usb" # Passes Google Coral USB TPU to the container "/dev/dri:/dev/dri" # Passes Intel/AMD GPU for hardware video decoding @@ -66,12 +66,12 @@ in { trigger = "server"; envFile = config.sops.secrets."FRIGATE_ENV".path; script = pkgs.writeShellScript "setup-frigate" '' - mkdir -p "${serverCfg.path.config}/frigate" + mkdir -p "${serverCfg.path.config.path}/frigate" mkdir -p "/var/lib/frigate/storage" # Bootstrap a standard configuration layout if missing - if [ ! -f "${serverCfg.path.config}/frigate/config.yml" ]; then - cat < "${serverCfg.path.config}/frigate/config.yml" + if [ ! -f "${serverCfg.path.config.path}/frigate/config.yml" ]; then + cat < "${serverCfg.path.config.path}/frigate/config.yml" mqtt: enabled: False # Set to True and define host if connecting to Home Assistant diff --git a/modules/server/containers/apps/gitea.nix b/modules/server/containers/apps/gitea.nix index 67f90d9..ec0158f 100644 --- a/modules/server/containers/apps/gitea.nix +++ b/modules/server/containers/apps/gitea.nix @@ -12,7 +12,7 @@ in { runtime = { paths = [{ - path="${serverCfg.path.data}/gitea"; + path="${serverCfg.path.data.path}/gitea"; owner = "1000:1000"; dirs = ["data" "runner"]; mode = "0755"; @@ -82,7 +82,7 @@ in { overrides = { volumes = [ - "${serverCfg.path.data}/gitea/data:/data" + "${serverCfg.path.data.path}/gitea/data:/data" ]; ports = [ "2222:22" ]; }; @@ -99,7 +99,7 @@ in { overrides = { volumes = [ - "${serverCfg.path.data}/gitea/runner:/data" + "${serverCfg.path.data.path}/gitea/runner:/data" "/var/run/podman/podman.sock:/var/run/docker.sock" ]; }; @@ -117,7 +117,7 @@ in { $GT admin user create --username "$DEFAULT_ADMIN_USERNAME" --password "$DEFAULT_ADMIN_PASSWORD" --email "$DEFAULT_ADMIN_EMAIL" --admin || true - touch ${serverCfg.path.data}/gitea/data-runner/config.yml + touch ${serverCfg.path.data.path}/gitea/data-runner/config.yml RUNNER_TOKEN=$($GT actions generate-runner-token) $GTR register \ diff --git a/modules/server/containers/apps/handbrake.nix b/modules/server/containers/apps/handbrake.nix index 7f11e41..500ee4b 100644 --- a/modules/server/containers/apps/handbrake.nix +++ b/modules/server/containers/apps/handbrake.nix @@ -5,7 +5,7 @@ let in { runtime = { paths = [{ - path = "${serverCfg.path.config}/handbrake"; + path = "${serverCfg.path.config.path}/handbrake"; mode = "0755"; }]; @@ -28,9 +28,9 @@ in { overrides = { volumes = [ - "${serverCfg.path.config}/handbrake:/config:rw" - "${serverCfg.path.dlComplete}:/watch:rw" - "${serverCfg.path.dlConverted}:/output:rw" + "${serverCfg.path.config.path}/handbrake:/config:rw" + "${serverCfg.path.dlComplete.path}:/watch:rw" + "${serverCfg.path.dlConverted.path}:/output:rw" ]; }; }; @@ -40,7 +40,7 @@ in { setup = { trigger = "server"; script = pkgs.writeShellScript "setup" '' - mkdir -p ${serverCfg.path.data}/handbrake/{watch,output} + mkdir -p ${serverCfg.path.data.path}/handbrake/{watch,output} ''; }; diff --git a/modules/server/containers/apps/immich.nix b/modules/server/containers/apps/immich.nix index e6b5d86..50cb6fa 100644 --- a/modules/server/containers/apps/immich.nix +++ b/modules/server/containers/apps/immich.nix @@ -11,11 +11,11 @@ in { runtime = { paths = [{ - path = "${serverCfg.path.config}/immich"; + path = "${serverCfg.path.config.path}/immich"; dirs = ["cache"]; mode = "0750"; }{ - path = "${serverCfg.path.data}/immich/"; + path = "${serverCfg.path.data.path}/immich/"; dirs = ["upload" "thumbs" "encoded-video" "backups"]; mode = "0755"; }]; @@ -38,10 +38,10 @@ in { }; overrides = { volumes = [ - "${serverCfg.path.photo}:/data/upload" - "${serverCfg.path.data}/immich/backups:/data/backups" - "${serverCfg.path.config}/immich/thumbs:/data/thumbs" - "${serverCfg.path.config}/immich/encoded-video:/data/encoded-video" + "${serverCfg.path.photo.path}:/data/upload" + "${serverCfg.path.data.path}/immich/backups:/data/backups" + "${serverCfg.path.config.path}/immich/thumbs:/data/thumbs" + "${serverCfg.path.config.path}/immich/encoded-video:/data/encoded-video" ]; }; }; @@ -51,7 +51,7 @@ in { port = 3003; overrides = { volumes = [ - "${serverCfg.path.config}/immich/cache:/cache" + "${serverCfg.path.config.path}/immich/cache:/cache" ]; }; }; diff --git a/modules/server/containers/apps/influx.nix b/modules/server/containers/apps/influx.nix index 9d9603a..5fc0ff4 100644 --- a/modules/server/containers/apps/influx.nix +++ b/modules/server/containers/apps/influx.nix @@ -34,11 +34,11 @@ in { runtime = { paths = [{ - path = "${serverCfg.path.config}/influxdb/"; + path = "${serverCfg.path.config.path}/influxdb/"; owner = "1500:1500"; mode = "0755"; }{ - path = "${serverCfg.path.data}/influxdb/"; + path = "${serverCfg.path.data.path}/influxdb/"; dirs = ["data" "ui"]; owner = "1500:1500"; mode = "0755"; @@ -56,8 +56,8 @@ in { cmd = [ "influxdb3" "serve" "--node-id=node0" "--data-dir=/var/lib/influxdb3/data" "--admin-token-file=/var/lib/influxdb3/token.json" ]; ports = [ "8181:8181" ]; volumes = [ - "${serverCfg.path.data}/influxdb/data:/var/lib/influxdb3/data:rw" - "${serverCfg.path.config}/influxdb/admin-token.json:/var/lib/influxdb3/token.json:ro" + "${serverCfg.path.data.path}/influxdb/data:/var/lib/influxdb3/data:rw" + "${serverCfg.path.config.path}/influxdb/admin-token.json:/var/lib/influxdb3/token.json:ro" ]; }; @@ -77,8 +77,8 @@ in { overrides = { cmd = [ "--mode=admin" ]; volumes = [ - "${serverCfg.path.data}/influxdb/ui:/db:rw" - "${serverCfg.path.config}/influxdb/:/app-root/config:rw" + "${serverCfg.path.data.path}/influxdb/ui:/db:rw" + "${serverCfg.path.config.path}/influxdb/:/app-root/config:rw" ]; }; } else builder.mkContainer { @@ -114,7 +114,7 @@ in { user = "1500:1500"; environmentFiles = [ config.sops.secrets."INFLUX".path config.sops.secrets."CUSTOM".path ] ; volumes = [ - "${serverCfg.path.data}/influxdb/ui:/var/lib/grafana:rw" + "${serverCfg.path.data.path}/influxdb/ui:/var/lib/grafana:rw" "${influxSource}:/etc/grafana/provisioning/datasources/influx.yaml:ro" ]; }; @@ -125,7 +125,7 @@ in { trigger = "db"; envFile = config.sops.secrets."INFLUX".path; script = pkgs.writeShellScript "setup" '' - cat > ${serverCfg.path.config}/influxdb/config.json << EOF + cat > ${serverCfg.path.config.path}/influxdb/config.json << EOF { "DEFAULT_INFLUX_SERVER": "http://${builder.host}:8181", "DEFAULT_INFLUX_DATABASE": "main", @@ -134,7 +134,7 @@ in { } EOF - cat > ${serverCfg.path.config}/influxdb/admin-token.json << EOF + cat > ${serverCfg.path.config.path}/influxdb/admin-token.json << EOF { "token": "$INFLUXDB_TOKEN", "name": "admin", diff --git a/modules/server/containers/apps/invidious.nix b/modules/server/containers/apps/invidious.nix index 164e128..e01a183 100644 --- a/modules/server/containers/apps/invidious.nix +++ b/modules/server/containers/apps/invidious.nix @@ -31,7 +31,7 @@ in { runtime = { paths = [{ - path="${serverCfg.path.config}/invidious"; + path="${serverCfg.path.config.path}/invidious"; mode = "0755"; }]; @@ -53,7 +53,7 @@ in { }; overrides = { volumes = [ - "${serverCfg.path.config}/invidious:/data:ro" + "${serverCfg.path.config.path}/invidious:/data:ro" ]; }; }; @@ -76,7 +76,7 @@ in { export DB_HOST=${builder.host} export INVIDIOUS_DOMAIN=${containerCfg.subdomain}.${serverCfg.domain} - ${pkgs.gettext}/bin/envsubst < "${../data/invidious/config.yml}" > "${serverCfg.path.config}/invidious/config.yml" + ${pkgs.gettext}/bin/envsubst < "${../data/invidious/config.yml}" > "${serverCfg.path.config.path}/invidious/config.yml" ''; }; }; diff --git a/modules/server/containers/apps/jellyfin.nix b/modules/server/containers/apps/jellyfin.nix index 71a2c04..832d890 100644 --- a/modules/server/containers/apps/jellyfin.nix +++ b/modules/server/containers/apps/jellyfin.nix @@ -28,7 +28,7 @@ in { runtime = { paths = [ { - path = "${serverCfg.path.config}/jellyfin/"; + path = "${serverCfg.path.config.path}/jellyfin/"; owner = "1000:1000"; mode = "0755"; } @@ -54,8 +54,8 @@ in { "--logdir" "/config/log" ]; volumes = [ - "${serverCfg.path.film}:/media:ro" - "${serverCfg.path.config}/jellyfin:/config" + "${serverCfg.path.film.path}:/media:ro" + "${serverCfg.path.config.path}/jellyfin:/config" ]; # If you have an Intel/AMD GPU for transcoding, add the device: devices = lib.optionals (builtins.pathExists "/dev/dri") [ "/dev/dri:/dev/dri" ]; @@ -163,7 +163,7 @@ in { fi ''} - ${pkgs.sqlite}/bin/sqlite3 ${serverCfg.path.config}/jellyfin/data/data/jellyfin.db < "${serverCfg.path.config}/transmission/config/settings.json" + ${pkgs.gettext}/bin/envsubst < "${../data/transmission/settings.json}" > "${serverCfg.path.config.path}/transmission/config/settings.json" ''; }; }; diff --git a/modules/server/containers/apps/umami.nix b/modules/server/containers/apps/umami.nix index b1ba347..d39af4a 100644 --- a/modules/server/containers/apps/umami.nix +++ b/modules/server/containers/apps/umami.nix @@ -22,7 +22,7 @@ in { runtime = { paths = [{ - path = "${serverCfg.path.config}/umami/"; + path = "${serverCfg.path.config.path}/umami/"; mode = "0444"; }]; diff --git a/modules/server/containers/default.nix b/modules/server/containers/default.nix index 2bb277a..217e743 100644 --- a/modules/server/containers/default.nix +++ b/modules/server/containers/default.nix @@ -13,10 +13,9 @@ let mergedContainers = lib.concatMapAttrs (appName: app: lib.mapAttrs' (cName: cCfg: lib.nameValuePair "${appName}-${cName}" cCfg) app.runtime.containers ) loadedContainers; - allPathConfigs = map (path: { - inherit path; - mode = "0755"; - }) (lib.unique (builtins.attrValues serverCfg.path)) ++ concatRuntimeLists "paths"; + allPathConfigs = + (lib.mapAttrsToList (_: cfg: cfg) serverCfg.path) + ++ concatRuntimeLists "paths"; allSetupConfigs = map (app: ({ name = app.name; envFile = ""; } // app.runtime.setup)) appsList; allCronsConfigs = concatRuntimeLists "cron"; allVMConfigs = builtins.filter (app: app.runtime.vm != null) appsList; diff --git a/modules/shared/syscfg/server.nix b/modules/shared/syscfg/server.nix index 7d9b466..4328f86 100644 --- a/modules/shared/syscfg/server.nix +++ b/modules/shared/syscfg/server.nix @@ -1,6 +1,28 @@ { lib,... }: let - + inherit (lib) mkOption; + inherit (lib.types) attrsOf coercedTo listOf str submodule nullOr port bool oneOf anything enum; + pathEntryType = coercedTo str (path: { inherit path; }) (submodule { + options = { + path = mkOption { type = str; }; + owner = mkOption { + type = str; + default = "root:root"; + }; + mode = mkOption { + type = str; + default = "0755"; + }; + dirs = mkOption { + type = listOf str; + default = [ ]; + }; + }; + }); + mkPathOption = defaultPath: defaults: mkOption { + type = pathEntryType; + default = { path = defaultPath; } // defaults; + }; in with lib; { domain = mkOption { type = types.str; }; mail = { @@ -11,21 +33,21 @@ in with lib; { path = mkOption { type = types.submodule { - freeformType = types.attrsOf types.str; + freeformType = attrsOf pathEntryType; options = { - config = mkOption { type = types.str; default = "/media/config"; }; - data = mkOption { type = types.str; default = "/media/data"; }; - download = mkOption { type = types.str; default = "/media/data/download"; }; - cloud = mkOption { type = types.str; default ="/media/media/cloud"; }; - film = mkOption { type = types.str; default ="/media/media/film"; }; - book = mkOption { type = types.str; default ="/media/media/book"; }; - manga = mkOption { type = types.str; default ="/media/media/manga"; }; - photo = mkOption { type = types.str; default ="/media/media/photo"; }; - # music = mkOption { type = types.str; default ="/media/media/music"; }; + config = mkPathOption "/media/config" { }; + data = mkPathOption "/media/data" { }; + download = mkPathOption "/media/data/download" { owner = "1000:1000"; }; + cloud = mkPathOption "/media/media/cloud" { owner = "33:33"; }; + film = mkPathOption "/media/media/film" { owner = "1000:1000"; }; + book = mkPathOption "/media/media/book" { owner = "1000:1000"; }; + manga = mkPathOption "/media/media/manga" { owner = "1000:1000"; }; + photo = mkPathOption "/media/media/photo" { owner = "1000:1000"; }; + # music = mkPathOption "/media/media/music" { owner = "1000:1000"; }; - dlComplete = mkOption { type = types.str; default ="/media/download/complete"; }; - dlIncomplete = mkOption { type = types.str; default ="/media/download/incomplete"; }; - dlConverted = mkOption { type = types.str; default ="/media/download/converted"; }; + dlComplete = mkPathOption "/media/download/complete" { owner = "1000:1000"; }; + dlIncomplete = mkPathOption "/media/download/incomplete" { owner = "1000:1000"; }; + dlConverted = mkPathOption "/media/download/converted" { owner = "1000:1000"; }; }; }; default = {};