{ config, pkgs, lib, ... }: with lib; let # Version tagging immichVersion = "v2.7.5"; redisVersion = "9@sha256:546304417feac0874c3dd576e0952c6bb8f06bb4093ea0c9ca303c73cf458f63"; databaseVersion = "14-vectorchord0.4.3-pgvectors0.2.0@sha256:bcf63357191b76a916ae5eb93464d65c07511da41e3bf7a8416db519b40b1c23"; # Helper helper = import ./lib.nix { inherit config pkgs lib; }; cfg = config.numbus.services.immich; # Container configuration name = "immich"; in helper.mkPodmanService { inherit name; description = "Immich, Google Photos but better"; defaultPort = "2283"; generatedSecrets = { DB_DATABASE_NAME = "xkcdpass -n 2 -d -"; DB_USERNAME = "xkcdpass -n 2 -d -"; DB_PASSWORD = "xkcdpass -n 8 -d -"; }; importedSecrets = { REDIS_HOSTNAME = "immich-redis"; DB_HOSTNAME = "immich-database"; UPLOAD_LOCATION = "${cfg.dataDir}"; DB_DATA_LOCATION = "${cfg.configDir}/database"; TZ = "${config.time.timeZone}"; IMMICH_VERSION = "v2.7.5"; }; middlewares = [ "immichSecureHeaders" ]; dirPermissions = [ "100999:100 ${cfg.configDir}" "100999:100 ${cfg.configDir}/redis" "100999:100 ${cfg.configDir}/model-cache" "100999:100 ${cfg.configDir}/machine-learning-cache" "100999:100 ${cfg.configDir}/machine-learning-config" "100999:100 ${cfg.configDir}/database" "100999:100 ${cfg.dataDir}" ]; # Compose file good composeText = '' services: immich-server: container_name: immich-server hostname: immich-server image: ghcr.io/immich-app/immich-server:${immichVersion} user: '1000:1000' networks: immich: ports: - "${cfg.port}:2283/tcp" volumes: - $UPLOAD_LOCATION:/data - /etc/localtime:/etc/localtime:ro env_file: - /var/lib/numbus-server/immich/.env environment: TZ: $TZ REDIS_HOSTNAME: $REDIS_HOSTNAME DB_HOSTNAME: $DB_HOSTNAME DB_DATABASE_NAME: $DB_DATABASE_NAME DB_USERNAME: $DB_USERNAME DB_PASSWORD: $DB_PASSWORD IMMICH_TRUSTED_PROXIES: ${config.numbus.networking.ipAddress} depends_on: - immich-redis - immich-database healthcheck: disable: false security_opt: - no-new-privileges:true cap_drop: - NET_RAW restart: unless-stopped immich-machine-learning: container_name: immich-machine-learning hostname: immich-machine-learning image: ghcr.io/immich-app/immich-machine-learning:${immichVersion} user: '1000:1000' networks: immich: volumes: - ${cfg.configDir}/model-cache:/cache - ${cfg.configDir}/machine-learning-config:/usr/src/.config - ${cfg.configDir}/machine-learning-cache:/usr/src/.cache/ env_file: - /var/lib/numbus-server/immich/.env healthcheck: disable: false security_opt: - no-new-privileges:true cap_drop: - NET_RAW restart: unless-stopped immich-redis: container_name: immich-redis hostname: immich-redis image: docker.io/valkey/valkey:${redisVersion} user: '1000:1000' networks: immich: volumes: - ${cfg.configDir}/redis:/data healthcheck: test: redis-cli ping || exit 1 restart: unless-stopped immich-database: container_name: immich-database hostname: immich-database image: ghcr.io/immich-app/postgres:${databaseVersion} user: '1000:1000' networks: immich: environment: POSTGRES_PASSWORD: $DB_PASSWORD POSTGRES_USER: $DB_USERNAME POSTGRES_DB: $DB_DATABASE_NAME POSTGRES_INITDB_ARGS: '--data-checksums' volumes: - $DB_DATA_LOCATION:/var/lib/postgresql/data shm_size: 128mb healthcheck: disable: false security_opt: - no-new-privileges:true cap_drop: - NET_RAW restart: unless-stopped networks: immich: name: immich driver: bridge ''; extraConfig = { environment.etc."traefik/rules/immichSecureHeaders.yaml".text = '' http: middlewares: immichSecureHeaders: headers: FrameDeny: true AccessControlAllowMethods: 'GET,POST,PUT,DELETE,OPTIONS' AccessControlAllowOriginList: - https://${cfg.subdomain}.${config.numbus.services.domain} - origin-list-or-null AccessControlMaxAge: 100 AddVaryHeader: true BrowserXssFilter: true ContentTypeNosniff: true ForceSTSHeader: true STSIncludeSubdomains: true STSPreload: true ContentSecurityPolicy: "default-src 'self'; base-uri 'self'; img-src 'self' https://static.immich.cloud https://tiles.immich.cloud data: blob:; connect-src 'self' https://${cfg.subdomain}.${config.numbus.services.domain} wss://${cfg.subdomain}.${config.numbus.services.domain} https://static.immich.cloud https://tiles.immich.cloud; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; script-src 'self' 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob: https://${cfg.subdomain}.${config.numbus.services.domain}; frame-ancestors 'self';" CustomFrameOptionsValue: SAMEORIGIN ReferrerPolicy: same-origin PermissionsPolicy: vibrate 'self' STSSeconds: 315360000 ''; }; }