nixos/immich: add enableVectors option

Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
This commit is contained in:
Sefa Eyeoglu
2025-07-26 12:13:21 +02:00
parent fd1994a8b7
commit 0b93bf6c22
6 changed files with 99 additions and 15 deletions

View File

@@ -198,7 +198,7 @@
- `services.ntpd-rs` now performs configuration validation. - `services.ntpd-rs` now performs configuration validation.
- Immich now has support for [VectorChord](https://github.com/tensorchord/VectorChord) when using the PostgreSQL configuration provided by `services.immich.database.enable`, which replaces `pgvecto-rs`. VectorChord support can be toggled with the option `services.immich.database.enableVectorChord`. - Immich now has support for [VectorChord](https://github.com/tensorchord/VectorChord) when using the PostgreSQL configuration provided by `services.immich.database.enable`, which replaces `pgvecto-rs`. VectorChord support can be toggled with the option `services.immich.database.enableVectorChord`. Additionally, `pgvecto-rs` support is now disabled from NixOS 25.11 onwards using the option `services.immich.database.enableVectors`. This option will be removed fully in the future once Immich drops support for `pgvecto-rs` fully.
- `services.postsrsd` now automatically integrates with the local Postfix instance, when enabled. This behavior can disabled using the [services.postsrsd.configurePostfix](#opt-services.postsrsd.configurePostfix) option. - `services.postsrsd` now automatically integrates with the local Postfix instance, when enabled. This behavior can disabled using the [services.postsrsd.configurePostfix](#opt-services.postsrsd.configurePostfix) option.

View File

@@ -187,6 +187,12 @@ in
// { // {
default = true; default = true;
}; };
enableVectors =
mkEnableOption "pgvecto.rs in the database. You may disable this, if you have migrated to VectorChord and deleted the `vectors` schema."
// {
default = lib.versionOlder config.system.stateVersion "25.11";
defaultText = lib.literalExpression "lib.versionOlder config.system.stateVersion \"25.11\"";
};
createDB = mkEnableOption "the automatic creation of the database for immich." // { createDB = mkEnableOption "the automatic creation of the database for immich." // {
default = true; default = true;
}; };
@@ -238,8 +244,14 @@ in
} }
{ {
# When removing this assertion, please adjust the nixosTests accordingly. # When removing this assertion, please adjust the nixosTests accordingly.
assertion = cfg.database.enable -> lib.versionOlder config.services.postgresql.package.version "17"; assertion =
message = "Immich doesn't support PostgreSQL 17+, yet."; (cfg.database.enable && cfg.database.enableVectors)
-> lib.versionOlder config.services.postgresql.package.version "17";
message = "Immich doesn't support PostgreSQL 17+ when using pgvecto.rs. Consider disabling it using services.immich.database.enableVectors if it is not needed anymore.";
}
{
assertion = cfg.database.enable -> (cfg.database.enableVectorChord || cfg.database.enableVectors);
message = "At least one of services.immich.database.enableVectorChord and services.immich.database.enableVectors has to be enabled.";
} }
]; ];
@@ -255,16 +267,17 @@ in
]; ];
extensions = extensions =
ps: ps:
[ ps.pgvecto-rs ] lib.optionals cfg.database.enableVectors [ ps.pgvecto-rs ]
++ lib.optionals cfg.database.enableVectorChord [ ++ lib.optionals cfg.database.enableVectorChord [
ps.vectors ps.pgvector
ps.vectorchord ps.vectorchord
]; ];
settings = { settings = {
shared_preload_libraries = [ shared_preload_libraries =
"vectors.so" lib.optionals cfg.database.enableVectors [
] "vectors.so"
++ lib.optionals cfg.database.enableVectorChord [ "vchord.so" ]; ]
++ lib.optionals cfg.database.enableVectorChord [ "vchord.so" ];
search_path = "\"$user\", public, vectors"; search_path = "\"$user\", public, vectors";
}; };
}; };
@@ -273,11 +286,13 @@ in
extensions = [ extensions = [
"unaccent" "unaccent"
"uuid-ossp" "uuid-ossp"
"vectors"
"cube" "cube"
"earthdistance" "earthdistance"
"pg_trgm" "pg_trgm"
] ]
++ lib.optionals cfg.database.enableVectors [
"vectors"
]
++ lib.optionals cfg.database.enableVectorChord [ ++ lib.optionals cfg.database.enableVectorChord [
"vector" "vector"
"vchord" "vchord"
@@ -286,7 +301,7 @@ in
${lib.concatMapStringsSep "\n" (ext: "CREATE EXTENSION IF NOT EXISTS \"${ext}\";") extensions} ${lib.concatMapStringsSep "\n" (ext: "CREATE EXTENSION IF NOT EXISTS \"${ext}\";") extensions}
ALTER SCHEMA public OWNER TO ${cfg.database.user}; ALTER SCHEMA public OWNER TO ${cfg.database.user};
ALTER SCHEMA vectors OWNER TO ${cfg.database.user}; ${lib.optionalString cfg.database.enableVectors "ALTER SCHEMA vectors OWNER TO ${cfg.database.user};"}
GRANT SELECT ON TABLE pg_vector_index_stat TO ${cfg.database.user}; GRANT SELECT ON TABLE pg_vector_index_stat TO ${cfg.database.user};
${lib.concatMapStringsSep "\n" (ext: "ALTER EXTENSION \"${ext}\" UPDATE;") extensions} ${lib.concatMapStringsSep "\n" (ext: "ALTER EXTENSION \"${ext}\" UPDATE;") extensions}

View File

@@ -741,6 +741,7 @@ in
ifm = runTest ./ifm.nix; ifm = runTest ./ifm.nix;
iftop = runTest ./iftop.nix; iftop = runTest ./iftop.nix;
immich = runTest ./web-apps/immich.nix; immich = runTest ./web-apps/immich.nix;
immich-vectorchord-migration = runTest ./web-apps/immich-vectorchord-migration.nix;
immich-public-proxy = runTest ./web-apps/immich-public-proxy.nix; immich-public-proxy = runTest ./web-apps/immich-public-proxy.nix;
incron = runTest ./incron.nix; incron = runTest ./incron.nix;
incus = pkgs.recurseIntoAttrs ( incus = pkgs.recurseIntoAttrs (

View File

@@ -0,0 +1,71 @@
{ ... }:
{
name = "immich-vectorchord-migration";
nodes.machine =
{ lib, pkgs, ... }:
{
# These tests need a little more juice
virtualisation = {
cores = 2;
memorySize = 2048;
diskSize = 4096;
};
environment.systemPackages = with pkgs; [ immich-cli ];
services.immich = {
enable = true;
environment.IMMICH_LOG_LEVEL = "verbose";
# Simulate an existing setup
database.enableVectorChord = lib.mkDefault false;
database.enableVectors = lib.mkDefault true;
};
# TODO: Remove when PostgreSQL 17 is supported.
services.postgresql.package = pkgs.postgresql_16;
specialisation."immich-vectorchord-enabled".configuration = {
services.immich.database.enableVectorChord = true;
};
specialisation."immich-vectorchord-only".configuration = {
services.immich.database = {
enableVectorChord = true;
enableVectors = false;
};
};
};
testScript =
{ nodes, ... }:
let
specBase = "${nodes.machine.system.build.toplevel}/specialisation";
vectorchordEnabled = "${specBase}/immich-vectorchord-enabled";
vectorchordOnly = "${specBase}/immich-vectorchord-only";
in
''
def psql(command: str):
machine.succeed(f"sudo -u postgres psql -d ${nodes.machine.services.immich.database.name} -c '{command}'")
def immich_works():
machine.wait_for_unit("immich-server.service")
machine.wait_for_open_port(2283) # Server
machine.wait_for_open_port(3003) # Machine learning
machine.succeed("curl --fail http://localhost:2283/")
immich_works()
machine.succeed("${vectorchordEnabled}/bin/switch-to-configuration test")
immich_works()
psql("DROP EXTENSION vectors;")
psql("DROP SCHEMA vectors;")
machine.succeed("${vectorchordOnly}/bin/switch-to-configuration test")
immich_works()
'';
}

View File

@@ -18,9 +18,6 @@
enable = true; enable = true;
environment.IMMICH_LOG_LEVEL = "verbose"; environment.IMMICH_LOG_LEVEL = "verbose";
}; };
# TODO: Remove when PostgreSQL 17 is supported.
services.postgresql.package = pkgs.postgresql_16;
}; };
testScript = '' testScript = ''

View File

@@ -273,7 +273,7 @@ buildNpmPackage' {
passthru = { passthru = {
tests = { tests = {
inherit (nixosTests) immich; inherit (nixosTests) immich immich-vectorchord-migration;
}; };
machine-learning = immich-machine-learning; machine-learning = immich-machine-learning;