feat: add immich module to yumeami tsuki host
All checks were successful
ci / treefmt (push) Successful in 2m10s
All checks were successful
ci / treefmt (push) Successful in 2m10s
This commit is contained in:
parent
72efc82c2a
commit
6a0b61a502
6 changed files with 106 additions and 12 deletions
|
|
@ -88,6 +88,7 @@ in {
|
|||
"forgejo"
|
||||
"grafana"
|
||||
"asciinema"
|
||||
"immich"
|
||||
"ntfy"
|
||||
"terraform"
|
||||
"vaultwarden"
|
||||
|
|
|
|||
|
|
@ -78,6 +78,14 @@ in {
|
|||
port = 5125;
|
||||
internal = true;
|
||||
};
|
||||
immich = {
|
||||
port = 2283;
|
||||
internal = true;
|
||||
websocket = {
|
||||
enable = true;
|
||||
path = "";
|
||||
};
|
||||
};
|
||||
jellyfin = {
|
||||
port = 8096;
|
||||
internal = true;
|
||||
|
|
|
|||
58
modules/nixos/services/apps/immich/default.nix
Normal file
58
modules/nixos/services/apps/immich/default.nix
Normal 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";
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
@ -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 = {
|
||||
port = port;
|
||||
};
|
||||
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.
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue