diff --git a/nixos/modules/services/web-apps/immich.nix b/nixos/modules/services/web-apps/immich.nix index 2224ca1d8ebb..6d9c909c4568 100644 --- a/nixos/modules/services/web-apps/immich.nix +++ b/nixos/modules/services/web-apps/immich.nix @@ -116,7 +116,7 @@ in description = '' Configuration for Immich. See or navigate to - for + for options and defaults. Setting it to `null` allows configuring Immich in the web interface. ''; @@ -270,7 +270,7 @@ in let postgresEnv = if isPostgresUnixSocket then - { DB_URL = "socket://${cfg.database.host}?dbname=${cfg.database.name}"; } + { DB_URL = "postgresql:///${cfg.database.name}?host=${cfg.database.host}"; } else { DB_HOSTNAME = cfg.database.host; @@ -317,6 +317,11 @@ in after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; inherit (cfg) environment; + path = [ + # gzip and pg_dumpall are used by the backup service + pkgs.gzip + config.services.postgresql.package + ]; serviceConfig = commonServiceConfig // { ExecStart = lib.getExe cfg.package; diff --git a/nixos/tests/web-apps/immich.nix b/nixos/tests/web-apps/immich.nix index 8004afd93c05..94a63fbfb9c1 100644 --- a/nixos/tests/web-apps/immich.nix +++ b/nixos/tests/web-apps/immich.nix @@ -31,21 +31,30 @@ import ../make-test-python.nix ( machine.succeed("curl --fail http://localhost:2283/") machine.succeed(""" - curl -H 'Content-Type: application/json' --data '{ "email": "test@example.com", "name": "Admin", "password": "admin" }' -X POST http://localhost:2283/api/auth/admin-sign-up + curl -f --json '{ "email": "test@example.com", "name": "Admin", "password": "admin" }' http://localhost:2283/api/auth/admin-sign-up """) res = machine.succeed(""" - curl -H 'Content-Type: application/json' --data '{ "email": "test@example.com", "password": "admin" }' -X POST http://localhost:2283/api/auth/login + curl -f --json '{ "email": "test@example.com", "password": "admin" }' http://localhost:2283/api/auth/login """) token = json.loads(res)['accessToken'] res = machine.succeed(""" - curl -H 'Content-Type: application/json' -H 'Cookie: immich_access_token=%s' --data '{ "name": "API Key", "permissions": ["all"] }' -X POST http://localhost:2283/api/api-keys + curl -f -H 'Cookie: immich_access_token=%s' --json '{ "name": "API Key", "permissions": ["all"] }' http://localhost:2283/api/api-keys """ % token) key = json.loads(res)['secret'] machine.succeed(f"immich login http://localhost:2283/api {key}") res = machine.succeed("immich server-info") print(res) + + machine.succeed(""" + curl -f -X PUT -H 'Cookie: immich_access_token=%s' --json '{ "command": "start" }' http://localhost:2283/api/jobs/backupDatabase + """ % token) + res = machine.succeed(""" + curl -f -H 'Cookie: immich_access_token=%s' http://localhost:2283/api/jobs + """ % token) + assert json.loads(res)["backupDatabase"]["jobCounts"]["active"] == 1 + machine.wait_until_succeeds("ls /var/lib/immich/backups/*.sql.gz") ''; } ) diff --git a/pkgs/by-name/im/immich/package.nix b/pkgs/by-name/im/immich/package.nix index a018bee46c88..bb1778ee207f 100644 --- a/pkgs/by-name/im/immich/package.nix +++ b/pkgs/by-name/im/immich/package.nix @@ -3,6 +3,7 @@ stdenvNoCC, buildNpmPackage, fetchFromGitHub, + fetchpatch2, python3, nodejs, node-gyp, @@ -17,12 +18,12 @@ cacert, unzip, # runtime deps + exiftool, jellyfin-ffmpeg, # Immich depends on the jellyfin customizations, see https://github.com/NixOS/nixpkgs/issues/351943 imagemagick, libraw, libheif, vips, - perl, }: let buildNpmPackage' = buildNpmPackage.override { inherit nodejs; }; @@ -146,6 +147,13 @@ buildNpmPackage' { src = "${src}/server"; inherit (sources.components.server) npmDepsHash; + postPatch = '' + # pg_dumpall fails without database root access + # see https://github.com/immich-app/immich/issues/13971 + substituteInPlace src/services/backup.service.ts \ + --replace-fail '`pg_dumpall`' '`pg_dump`' + ''; + nativeBuildInputs = [ pkg-config python3 @@ -166,7 +174,7 @@ buildNpmPackage' { makeCacheWritable = true; preBuild = '' - cd node_modules/sharp + pushd node_modules/sharp mkdir node_modules ln -s ${node-addon-api} node_modules/node-addon-api @@ -175,8 +183,13 @@ buildNpmPackage' { rm -r node_modules - cd ../.. + popd rm -r node_modules/@img/sharp* + + # If exiftool-vendored.pl isn't found, exiftool is searched for on the PATH + rm -r node_modules/exiftool-vendored.* + substituteInPlace node_modules/exiftool-vendored/dist/DefaultExifToolOptions.js \ + --replace-fail "checkPerl: !(0, IsWin32_1.isWin32)()," "checkPerl: false," ''; installPhase = '' @@ -197,7 +210,7 @@ buildNpmPackage' { --set IMMICH_BUILD_DATA $out/build --set NODE_ENV production \ --suffix PATH : "${ lib.makeBinPath [ - perl + exiftool jellyfin-ffmpeg ] }" diff --git a/pkgs/by-name/im/immich/sources.json b/pkgs/by-name/im/immich/sources.json index 3c4bdf53f702..f58bc75177a1 100644 --- a/pkgs/by-name/im/immich/sources.json +++ b/pkgs/by-name/im/immich/sources.json @@ -1,22 +1,22 @@ { - "version": "1.119.1", - "hash": "sha256-T+bIL2LaVNgFT3xBUxiEzhyDiLpw/WU7mxttuJD39SQ=", + "version": "1.120.1", + "hash": "sha256-FKPs6BHOXmqnHh2yH+PPBFQoK5ykP716dNvES/45t4g=", "components": { "cli": { - "npmDepsHash": "sha256-kTBlo6eIPswZC0GQG7IoqQZ5b7wPEXFaD/SuuaEQMEg=", - "version": "2.2.28" + "npmDepsHash": "sha256-5JmcDjLAVXhF3TH0M88dKLYPDsSctcOGPz9nV1n3k9c=", + "version": "2.2.30" }, "server": { - "npmDepsHash": "sha256-zgzqh3TyafPKuk5RZ2I/haYFzMVlI4jGnwD5XLqTBdg=", - "version": "1.119.1" + "npmDepsHash": "sha256-u2ZQv+z8uyn7z52V+7hNRWgnHVm4xMdhjspPqsLHYek=", + "version": "1.120.1" }, "web": { - "npmDepsHash": "sha256-LPtsMzF7yYGrrpDoYoba6OQphKY7AvGbJpPc5pS4eFU=", - "version": "1.119.1" + "npmDepsHash": "sha256-EAFUOhcmE1TfUBN0uxzuNkHibdaDRn8Lxvma70UJqDE=", + "version": "1.120.1" }, "open-api/typescript-sdk": { - "npmDepsHash": "sha256-dyKmDez8jO6p+cmSa2KMe9zzhXn4on3aFUMdep+gjzU=", - "version": "1.119.1" + "npmDepsHash": "sha256-AJcK5NE+ZNAK2FJblY32jtYxY0Z9npH92A3htcPes4A=", + "version": "1.120.1" } } }