nixos/immich: switch to genJqSecretsReplacement and deprecate secretSettings

This commit is contained in:
oddlama
2025-11-09 23:23:59 +01:00
parent b615f1825d
commit c01c527917
2 changed files with 30 additions and 48 deletions
+23 -41
View File
@@ -2,6 +2,7 @@
config,
lib,
pkgs,
utils,
...
}:
let
@@ -9,10 +10,9 @@ let
format = pkgs.formats.json { };
isPostgresUnixSocket = lib.hasPrefix "/" cfg.database.host;
isRedisUnixSocket = lib.hasPrefix "/" cfg.redis.host;
# convert a Nix attribute path to jq object identifier-index:
# https://jqlang.org/manual/#object-identifier-index
attrPathToIndex = attrPath: "." + lib.concatStringsSep "." attrPath;
secretsReplacement = utils.genJqSecretsReplacement {
loadCredential = true;
} cfg.settings "/run/immich/config.json";
commonServiceConfig = {
Type = "simple";
@@ -55,6 +55,22 @@ let
if cfg.database.enable then config.services.postgresql.package else pkgs.postgresql;
in
{
imports = [
(lib.mkRemovedOptionModule
[
"services"
"immich"
"secretSettings"
]
''
`secretSettings` has been deprecated as secrets can now be specified
directly in `settings`. To do so, set `_secret` of the desired
attribute to a file path, for example:
`services.immich.settings.oauth.clientSecret._secret = "/path/to/secret/file";`
''
)
];
options.services.immich = {
enable = mkEnableOption "Immich";
package = lib.mkPackageOption pkgs "immich" { };
@@ -128,6 +144,7 @@ in
<https://my.immich.app/admin/system-settings> for
options and defaults.
Setting it to `null` allows configuring Immich in the web interface.
You can load secret values from a file in this configuration by setting `somevalue._secret = "/path/to/file"` instead of setting `somevalue` directly.
'';
type = types.nullOr (
types.submodule {
@@ -151,27 +168,6 @@ in
);
};
secretSettings = mkOption {
default = { };
description = ''
Secrets to to be added to the JSON file generated from {option}`settings`, read from files.
'';
example = lib.literalExpression ''
{
notifications.smtp.transport.password = "/path/to/secret";
oauth.clientSecret = "/path/to/other/secret";
}
'';
type =
let
inherit (types) attrsOf either path;
recursiveType = either (attrsOf recursiveType) path // {
description = "nested " + (attrsOf path).description;
};
in
recursiveType;
};
machine-learning = {
enable =
mkEnableOption "immich's machine-learning functionality to detect faces and search for objects"
@@ -424,24 +420,10 @@ in
postgresqlPackage
];
preStart = mkIf (cfg.settings != null) (
''
cat '${format.generate "immich-config.json" cfg.settings}' > /run/immich/config.json
''
+ lib.concatStrings (
lib.mapAttrsToListRecursive (attrPath: _: ''
tmp="$(mktemp)"
${lib.getExe pkgs.jq} --rawfile secret "$CREDENTIALS_DIRECTORY/${attrPathToIndex attrPath}" \
'${attrPathToIndex attrPath} = ($secret | rtrimstr("\n"))' /run/immich/config.json > "$tmp"
mv "$tmp" /run/immich/config.json
'') cfg.secretSettings
)
);
preStart = mkIf (cfg.settings != null) secretsReplacement.script;
serviceConfig = commonServiceConfig // {
LoadCredential = lib.mapAttrsToListRecursive (
attrPath: file: "${attrPathToIndex attrPath}:${file}"
) cfg.secretSettings;
LoadCredential = secretsReplacement.credentials;
ExecStart = lib.getExe cfg.package;
EnvironmentFile = mkIf (cfg.secretsFile != null) cfg.secretsFile;
Slice = "system-immich.slice";
+7 -7
View File
@@ -17,14 +17,14 @@
services.immich = {
enable = true;
environment.IMMICH_LOG_LEVEL = "verbose";
settings.backup.database = {
enabled = true;
cronExpression = "invalid";
};
secretSettings = {
backup.database.cronExpression = "${pkgs.writeText "cron" "0 02 * * *"}";
settings = {
backup.database = {
enabled = true;
# Test loading secrets from files:
cronExpression._secret = "${pkgs.writeText "cron" "0 02 * * *"}";
};
# thanks to LoadCredential files only readable by root should work
notifications.smtp.transport.password = "/etc/shadow";
notifications.smtp.transport.password._secret = "/etc/shadow";
};
};