nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at python-updates 319 lines 7.8 kB view raw
1{ 2 lib, 3 stdenv, 4 fetchFromGitHub, 5 fetchPnpmDeps, 6 pnpmConfigHook, 7 pnpm_10, 8 python3, 9 nodejs, 10 node-gyp, 11 runCommand, 12 nixosTests, 13 immich-machine-learning, 14 # build-time deps 15 pkg-config, 16 makeWrapper, 17 binaryen, 18 curl, 19 cacert, 20 extism-js, 21 unzip, 22 # runtime deps 23 cairo, 24 exiftool, 25 giflib, 26 jellyfin-ffmpeg, # Immich depends on the jellyfin customizations, see https://github.com/NixOS/nixpkgs/issues/351943 27 imagemagick, 28 libjpeg, 29 libpng, 30 libraw, 31 libheif, 32 librsvg, 33 pango, 34 perl, 35 pixman, 36 vips_8_17, # thumbnail generation fails with vips 8.18 37 buildPackages, 38}: 39let 40 pnpm = pnpm_10; 41 42 esbuild' = buildPackages.esbuild.override { 43 buildGoModule = 44 args: 45 buildPackages.buildGoModule ( 46 args 47 // rec { 48 version = "0.25.5"; 49 src = fetchFromGitHub { 50 owner = "evanw"; 51 repo = "esbuild"; 52 tag = "v${version}"; 53 hash = "sha256-jemGZkWmN1x2+ZzJ5cLp3MoXO0oDKjtZTmZS9Be/TDw="; 54 }; 55 vendorHash = "sha256-+BfxCyg0KkDQpHt/wycy/8CTG6YBA/VJvJFhhzUnSiQ="; 56 } 57 ); 58 }; 59 60 buildLock = { 61 sources = 62 map 63 (p: { 64 name = p.pname; 65 inherit (p) version; 66 inherit (p.src) rev; 67 }) 68 [ 69 imagemagick 70 libheif 71 libraw 72 ]; 73 74 packages = [ ]; 75 }; 76 77 # The geodata website is not versioned, so we use the internet archive 78 geodata = 79 let 80 timestamp = "20250818205425"; 81 date = 82 "${lib.substring 0 4 timestamp}-${lib.substring 4 2 timestamp}-${lib.substring 6 2 timestamp}T" 83 + "${lib.substring 8 2 timestamp}:${lib.substring 10 2 timestamp}:${lib.substring 12 2 timestamp}Z"; 84 in 85 runCommand "immich-geodata" 86 { 87 outputHash = "sha256-zZHAomW1C4qReFbhme5dkVnTiLw+jmhZhzuYvoBVBCY="; 88 outputHashMode = "recursive"; 89 nativeBuildInputs = [ 90 cacert 91 curl 92 unzip 93 ]; 94 95 meta.license = lib.licenses.cc-by-40; 96 } 97 '' 98 mkdir $out 99 url="https://web.archive.org/web/${timestamp}/http://download.geonames.org/export/dump" 100 curl -Lo ./cities500.zip "$url/cities500.zip" 101 curl -Lo $out/admin1CodesASCII.txt "$url/admin1CodesASCII.txt" 102 curl -Lo $out/admin2Codes.txt "$url/admin2Codes.txt" 103 curl -Lo $out/ne_10m_admin_0_countries.geojson \ 104 https://github.com/nvkelso/natural-earth-vector/raw/ca96624a56bd078437bca8184e78163e5039ad19/geojson/ne_10m_admin_0_countries.geojson 105 106 unzip ./cities500.zip -d $out/ 107 echo "${date}" > $out/geodata-date.txt 108 ''; 109 110 # Without this thumbnail generation for raw photos fails with 111 # Error: Input file has corrupt header: tiff2vips: samples_per_pixel not a whole number of bytes 112 vips' = vips_8_17.overrideAttrs (prev: { 113 mesonFlags = prev.mesonFlags ++ [ "-Dtiff=disabled" ]; 114 }); 115in 116stdenv.mkDerivation (finalAttrs: { 117 pname = "immich"; 118 version = "2.5.2"; 119 120 src = fetchFromGitHub { 121 owner = "immich-app"; 122 repo = "immich"; 123 tag = "v${finalAttrs.version}"; 124 hash = "sha256-e3gU2pSnbYQQU3SxGaJs8dwfTMpeGTz7dcFCmc7Pi/o="; 125 }; 126 127 pnpmDeps = fetchPnpmDeps { 128 inherit (finalAttrs) pname version src; 129 inherit pnpm; 130 fetcherVersion = 3; 131 hash = "sha256-+2rm184Hb+S75VyDn3FU36M/3SH2hUDYbKotIGopmvU="; 132 }; 133 134 postPatch = '' 135 # pg_dumpall fails without database root access 136 # see https://github.com/immich-app/immich/issues/13971 137 substituteInPlace server/src/utils/database-backups.ts \ 138 --replace-fail '`/usr/lib/postgresql/''${databaseMajorVersion}/bin/''${bin}`' '`''${bin}`' 139 ''; 140 141 nativeBuildInputs = [ 142 nodejs 143 pkg-config 144 pnpmConfigHook 145 pnpm 146 python3 147 makeWrapper 148 node-gyp # for building node_modules/sharp from source 149 ]; 150 151 buildInputs = [ 152 jellyfin-ffmpeg 153 imagemagick 154 libraw 155 libheif 156 # https://github.com/Automattic/node-canvas/blob/master/Readme.md#compiling 157 cairo 158 giflib 159 libjpeg 160 libpng 161 librsvg 162 pango 163 pixman 164 # Required for sharp 165 vips' 166 ]; 167 168 env.SHARP_FORCE_GLOBAL_LIBVIPS = 1; 169 env.ESBUILD_BINARY_PATH = lib.getExe esbuild'; 170 # fix for node-gyp, see https://github.com/nodejs/node-gyp/issues/1191#issuecomment-301243919 171 env.npm_config_nodedir = nodejs; 172 173 buildPhase = '' 174 runHook preBuild 175 176 # If exiftool-vendored.pl isn't found, exiftool is searched for on the PATH 177 rm node_modules/.pnpm/node_modules/exiftool-vendored.pl 178 179 pnpm --filter immich build 180 181 runHook postBuild 182 ''; 183 184 installPhase = '' 185 runHook preInstall 186 187 local -r packageOut="$out/lib/node_modules/immich" 188 189 # install node_modules and built files in $out 190 # upstream uses pnpm deploy to build their docker images 191 pnpm --filter immich deploy --prod --no-optional "$packageOut" 192 193 # remove build artifacts that bloat the closure 194 find "$packageOut/node_modules" \( \ 195 -name config.gypi \ 196 -o -name .deps \ 197 -o -name '*Makefile' \ 198 -o -name '*.target.mk' \ 199 \) -exec rm -r {} + 200 201 mkdir -p "$packageOut/build" 202 ln -s '${finalAttrs.passthru.plugins}' "$packageOut/build/corePlugin" 203 ln -s '${finalAttrs.passthru.web}' "$packageOut/build/www" 204 ln -s '${geodata}' "$packageOut/build/geodata" 205 206 echo '${builtins.toJSON buildLock}' > "$packageOut/build/build-lock.json" 207 208 makeWrapper '${lib.getExe nodejs}' "$out/bin/immich-admin" \ 209 --add-flags "$packageOut/dist/main" \ 210 --add-flags immich-admin 211 makeWrapper '${lib.getExe nodejs}' "$out/bin/server" \ 212 --add-flags "$packageOut/dist/main" \ 213 --chdir "$packageOut" \ 214 --set IMMICH_BUILD_DATA "$packageOut/build" \ 215 --set NODE_ENV production \ 216 --suffix PATH : '${ 217 lib.makeBinPath [ 218 exiftool 219 jellyfin-ffmpeg 220 perl # exiftool-vendored checks for Perl even if exiftool comes from $PATH 221 ] 222 }' 223 224 runHook postInstall 225 ''; 226 227 passthru = { 228 tests = { 229 inherit (nixosTests) immich immich-vectorchord-migration immich-vectorchord-reindex; 230 }; 231 232 machine-learning = immich-machine-learning.override { 233 immich = finalAttrs.finalPackage; 234 }; 235 236 plugins = stdenv.mkDerivation { 237 pname = "immich-plugins"; 238 inherit (finalAttrs) version src pnpmDeps; 239 240 nativeBuildInputs = [ 241 binaryen 242 extism-js 243 nodejs 244 pnpmConfigHook 245 pnpm 246 ]; 247 248 buildPhase = '' 249 runHook preBuild 250 251 pnpm --filter plugins build 252 253 runHook postBuild 254 ''; 255 256 installPhase = '' 257 runHook preInstall 258 259 cd plugins 260 mkdir $out 261 cp -r dist manifest.json $out 262 263 runHook postInstall 264 ''; 265 }; 266 267 web = stdenv.mkDerivation { 268 pname = "immich-web"; 269 inherit (finalAttrs) version src pnpmDeps; 270 271 nativeBuildInputs = [ 272 nodejs 273 pnpmConfigHook 274 pnpm 275 ]; 276 277 buildPhase = '' 278 runHook preBuild 279 280 pnpm --filter @immich/sdk build 281 pnpm --filter immich-web build 282 283 runHook postBuild 284 ''; 285 286 installPhase = '' 287 runHook preInstall 288 289 cd web 290 cp -r build $out 291 292 runHook postInstall 293 ''; 294 }; 295 296 inherit 297 geodata 298 pnpm 299 ; 300 }; 301 302 meta = { 303 changelog = "https://github.com/immich-app/immich/releases/tag/${finalAttrs.src.tag}"; 304 description = "Self-hosted photo and video backup solution"; 305 homepage = "https://immich.app/"; 306 license = with lib.licenses; [ 307 agpl3Only 308 cc-by-40 # geonames 309 ]; 310 maintainers = with lib.maintainers; [ 311 dotlambda 312 jvanbruegge 313 Scrumplex 314 titaniumtown 315 ]; 316 platforms = lib.platforms.linux ++ lib.platforms.freebsd; 317 mainProgram = "server"; 318 }; 319})