feat: add immich module to yumeami tsuki host
All checks were successful
ci / treefmt (push) Successful in 2m10s

This commit is contained in:
Ceferino Patino 2026-06-30 23:43:49 -05:00
commit 6a0b61a502
Signed by: c4patino
SSH key fingerprint: SHA256:Wu+cU1t+7zVT9wzew/4meNmeulo66NzMqc22MdDBgXI
6 changed files with 106 additions and 12 deletions

View file

@ -88,6 +88,7 @@ in {
"forgejo"
"grafana"
"asciinema"
"immich"
"ntfy"
"terraform"
"vaultwarden"

View file

@ -78,6 +78,14 @@ in {
port = 5125;
internal = true;
};
immich = {
port = 2283;
internal = true;
websocket = {
enable = true;
path = "";
};
};
jellyfin = {
port = 8096;
internal = true;

View file

@ -0,0 +1,58 @@
{
config,
lib,
namespace,
...
}: let
inherit (lib) mkIf;
inherit (lib.${namespace}) getAttrByNamespace resolveDatabaseHost resolveDatabaseIP hostHasService resolveServicePort;
inherit (config.networking) hostName;
pgCfg = getAttrByNamespace config "${namespace}.services.storage.postgresql";
networkCfg = getAttrByNamespace config "${namespace}.services.networking";
isEnabled = hostHasService networkCfg.network-services hostName "immich";
port = resolveServicePort networkCfg.network-services "immich" 2283;
in {
config = mkIf isEnabled {
services.immich = {
enable = true;
host = "0.0.0.0";
port = port;
openFirewall = true;
database = {
enable = false;
host = resolveDatabaseIP networkCfg.devices pgCfg.databases "immich";
port = 5600;
name = "immich";
user = "immich";
};
secretsFile = config.sops.secrets."environment-file/immich".path;
settings.server.externalDomain = "https://photos.yumeami.sh";
};
systemd.services.immich-server = let
dbHost = resolveDatabaseHost pgCfg.databases "immich";
in
mkIf (dbHost == hostName) {
after = ["postgresql.service" "pgbouncer.service"];
requires = ["postgresql.service" "pgbouncer.service"];
};
sops.secrets."environment-file/immich" = {};
${namespace}.services.storage.impermanence.folders = let
immichUser = config.users.users.immichUser;
in [
{
directory = "/var/lib/immich";
user = immichUser.name;
group = immichUser.group;
mode = "700";
}
];
};
}

View file

@ -6,7 +6,7 @@
pkgs,
...
} @ args: let
inherit (lib) types mkIf concatStringsSep hasAttr getAttr filter;
inherit (lib) types mkIf mkMerge concatStringsSep hasAttr getAttr filter optionalString head splitString;
inherit (lib.${namespace}) getAttrByNamespace mkOptionsWithNamespace readJsonOrEmpty getIn mkOptAttrset;
inherit (config.networking) hostName;
base = "${namespace}.services.storage.postgresql";
@ -26,7 +26,7 @@ in {
config = mkIf (hasAttr hostName cfg.databases) (let
hostDatabases = getAttr hostName cfg.databases;
mainServices = filter (db: !(lib.hasSuffix "-log" db)) hostDatabases;
logDatabases = filter (lib.hasSuffix "-log") hostDatabases;
auxDbs = filter (lib.hasSuffix "-log") hostDatabases;
in {
services = {
postgresql = {
@ -34,9 +34,21 @@ in {
enableTCPIP = true;
package = pkgs.postgresql_17;
settings = {
settings = mkMerge [
{
port = port;
};
}
(mkIf (builtins.elem "immich" mainServices) {
shared_preload_libraries = ["vchord.so"];
search_path = "\"$user\", public, vectors";
})
];
extensions = mkIf (builtins.elem "immich" mainServices) (ps:
with ps; [
pgvector
vectorchord
]);
authentication = let
permissionEntries =
@ -105,14 +117,28 @@ in {
ALTER FUNCTION public.pgbouncer_lookup(text) SET search_path = pg_catalog;
GRANT EXECUTE ON FUNCTION public.pgbouncer_lookup(text) TO pgbouncer_auth;
${concatStringsSep "\n" (map (logDb: let
mainUser = lib.removeSuffix "-log" logDb;
${
auxDbs
|> map (db: let
user = head (splitString "-" db);
in ''
GRANT ALL PRIVILEGES ON DATABASE "${logDb}" TO "${mainUser}";
ALTER DATABASE "${logDb}" OWNER TO "${mainUser}";
GRANT ALL PRIVILEGES ON DATABASE "${db}" TO "${user}";
ALTER DATABASE "${db}" OWNER TO "${user}";
'')
logDatabases)}
|> concatStringsSep "\n"
}
SQL
${
optionalString (builtins.elem "immich" mainServices) ''
${
["unaccent" "uuid-ossp" "cube" "earthdistance" "pg_trgm" "vector" "vchord"]
|> map (ext: "psql -d immich -v ON_ERROR_STOP=1 -c 'CREATE EXTENSION IF NOT EXISTS \"${ext}\";'")
|> concatStringsSep "\n"
}
psql -d immich -v ON_ERROR_STOP=1 -c 'ALTER SCHEMA public OWNER TO immich;'
''
}
'';
});
}

Binary file not shown.

View file

@ -16,6 +16,7 @@ environment-file:
autobrr: ENC[AES256_GCM,data:EXuYnWKHk0cwFWdMUaU/aapaPlY4o0/WjwlBenIM9aqOQ9jZ8bqQEcSeP8iHg9XjDJFNpxwSTsDCp3sB6jXrqAbR6Q==,iv:rhRvRE5+1VfcGcWjm4rGrs8fPzttp5WgHGpjnwcgSV4=,tag:RNK3Xp+NGeUSOgWC9uUsCA==,type:str]
bazarr: ENC[AES256_GCM,data:vDTjMrKEoGdnx1ABTAuA0k3kogR2tV4z9jvXVj52B2YVDRa4MPN/CWRXtAR1u0jysf7rE3NJMsBv3nQgOpI=,iv:ahQlJt+aok0vkgVD85qdpIEX0rxE9qcUOQWH7abqa0w=,tag:DzogkL9XBDJNBsiUgBwHIw==,type:str]
glance: ENC[AES256_GCM,data:/T/ItEwjzvLj1/p3ldFu+dorzOWUSDcxrljPiYJ1j/9PIJZMJkZ2BYIXIt8FwwnA1Omwl6QoJwN9H/GiT2we69ucVnic0i3SchDHuM3rXA9/xuvUB61rzXdx3fQ9T7LbJ6cA77oApCBCOA==,iv:LlsIVEhUot5YJpTzi6uvL/i2hrfAxnP3pZOOV9L8Xvs=,tag:/Fnh+WgtZXfSb9pWe1m1Mw==,type:str]
immich: ENC[AES256_GCM,data:ebaICuhFvHeJek8px2PLPYHY21rrfDe3QMj/WSwsnfCrzKnZ20eKxyU2InzSi0KN2hJ4xuhYeJI=,iv:wFMblYyr+ENXQxZwBhQLBvDA4ERmZPjkurn/pIuzYc4=,tag:0OZg/lGC/Lti2XtfAXZXUg==,type:str]
lidarr: ENC[AES256_GCM,data:F75i9YOqcFPVICggm+JHJB+jor2PNAAfyu/Zsj+zptqtJh0nJMMpfctuEYRyc1k0y/VGssPDu8FqEqH44kmgn4L1cmsLcAM=,iv:6JvmnIAG4GUebD7DoLrGt/G/tUrbAiZUDlGZUHxxmbY=,tag:U9wB+cKXM3kSnbADmfTmzw==,type:str]
ntfy: ENC[AES256_GCM,data:JB+h4r+QXerD8PbT35RwM556RY63mTNvBN31rIZA7gVkqfa33tLco1fNkFyysA+qpTKaraKpGgmlC6yBgWi5dc7My2CzEHKqqEAV6CJ24Tj00F1aXOunw8BsEBCYuVeHpbIsEtikbkTQ6d0r5bAXdlrL8zyD,iv:/zLYKwDcaNWR3lBqH+IPuwsPnq59SQHaMGSEY+ADJ/w=,tag:+WMzRX+YPaW8dMvJsAAcVQ==,type:str]
prowlarr: ENC[AES256_GCM,data:l1aDFg/alG7CDkkwufzMjQ2/6ZLnMvBO/GodS2txktvjRCeoc+qfL4Xf4T6JCltVHTHTl8P3Y0GlWoZ0VPbuP/L+UmV/jZKBvA==,iv:xnXc5TGd1zpDCvaN2IzdI2R/t8C0hTJaLVsP6u3fNsU=,tag:4ZkRyc1aCZoY59X9zIV5gw==,type:str]
@ -168,7 +169,7 @@ sops:
yUtR1lCjpW5Hpi2vDoom4HDsodeXfazqS+RjpHuKOLeO39bb4KbAhg==
-----END AGE ENCRYPTED FILE-----
recipient: age1988jz0qfj6m9xfenhd292tkxwyxvzhv79gkgrhm0gep353kej3yqe6zp86
lastmodified: "2026-06-30T19:23:37Z"
mac: ENC[AES256_GCM,data:FewAMhmopqxq6N6elvjIVmyR+LaQCh/ItQFVU0tSUInp6+qz6jPb1gKYqOI0pOU0C5euBV02K39afY8vrJBc8hM7AD+talKGXmgNULX3f4JWOnNrfOgFhgoqXTgWrU+kAEHmM5ZNlFICYeEow6i+/t6DAlVFuylrCpFokJLH0bU=,iv:7QnAu29thDRu/AamlvyjgZp4MwoiScELDByLSDWTjV0=,tag:y++WaY41XP/ifUo7IqKZZw==,type:str]
lastmodified: "2026-07-01T03:01:47Z"
mac: ENC[AES256_GCM,data:YU7Bz3jfzZBcRS8988PEelyk0ILGDIMYMOm3dmX1CS2vEmPdYS4F90JS5msyniV8FEvygsZg9Es5UvijEvXCwLHFi8DCsisRREQkjng6Y0HlpYxZ3vkX1ayYqNz6HgtZyLh8SeMvxUJO9fI69NzhW9lw7xvgeSnnNz2DVu2kqqg=,iv:tys6hfzw6qUXXMNMtPx8cydGLJLbT6OEBxQaCAt8LwU=,tag:niCSLPegApsGkK02Xh4XSA==,type:str]
unencrypted_suffix: _unencrypted
version: 3.13.1