{ myLib, ... }: { kubernetes.resources = { deployments = { immich.spec = { selector.matchLabels = { app = "immich"; component = "server"; }; strategy = { type = "RollingUpdate"; rollingUpdate = { maxSurge = 0; maxUnavailable = 1; }; }; template = { metadata.labels = { app = "immich"; component = "server"; }; spec = { volumes.data.persistentVolumeClaim.claimName = "data"; enableServiceLinks = false; containers.immich = { image = "ghcr.io/immich-app/immich-server:v1.108.0"; imagePullPolicy = "IfNotPresent"; ports.web.containerPort = 3001; env = { TZ.value = "Europe/Amsterdam"; REDIS_HOSTNAME.value = "redis.immich.svc.cluster.local"; DB_HOSTNAME.value = "postgres.immich.svc.cluster.local"; DB_USERNAME.value = "postgres"; DB_PASSWORD.value = "ref+sops://secrets/kubernetes.yaml#/immich/databasePassword"; DB_DATABASE_NAME.value = "immich"; IMMICH_MACHINE_LEARNING_URL.value = "http://ml.immich.svc.cluster.local"; }; volumeMounts = [{ name = "data"; mountPath = "/usr/src/app/upload"; }]; }; }; }; }; ml.spec = { selector.matchLabels = { app = "immich"; component = "machine-learning"; }; template = { metadata.labels = { app = "immich"; component = "machine-learning"; }; spec = { volumes.cache.persistentVolumeClaim.claimName = "cache"; containers.machine-learning = { image = "ghcr.io/immich-app/immich-machine-learning:v1.108.0"; imagePullPolicy = "IfNotPresent"; ports.ml.containerPort = 3003; env.MACHINE_LEARNING_WORKER_TIMEOUT.value = "600"; volumeMounts = [{ name = "cache"; mountPath = "/cache"; }]; }; }; }; }; redis.spec = { selector.matchLabels = { app = "immich"; component = "redis"; }; strategy = { type = "RollingUpdate"; rollingUpdate = { maxSurge = 0; maxUnavailable = 1; }; }; template = { metadata.labels = { app = "immich"; component = "redis"; }; spec = { containers.redis = { image = "docker.io/redis:6.2-alpine@sha256:d6c2911ac51b289db208767581a5d154544f2b2fe4914ea5056443f62dc6e900"; ports.redis.containerPort = 6379; imagePullPolicy = "IfNotPresent"; }; }; }; }; database.spec = { selector.matchLabels = { app = "immich"; component = "database"; }; strategy = { type = "RollingUpdate"; rollingUpdate = { maxSurge = 0; maxUnavailable = 1; }; }; template = { metadata.labels = { app = "immich"; component = "database"; }; spec = { volumes.data.persistentVolumeClaim.claimName = "database"; containers.postgres = { image = "docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0"; imagePullPolicy = "IfNotPresent"; command = [ "postgres" ]; args = [ "-c" "shared_preload_libraries=vectors.so" "-c" "search_path=\"$$user\", public, vectors" "-c" "logging_collector=on" "-c" "max_wal_size=2GB" "-c" "shared_buffers=512MB" "-c" "wal_compression=on" ]; ports.postgres.containerPort = 5432; securityContext.runAsUser = 999; securityContext.runAsGroup = 999; env = { POSTGRES_PASSWORD.value = "ref+sops://secrets/kubernetes.yaml#/immich/databasePassword"; POSTGRES_USER.value = "postgres"; POSTGRES_DB.value = "immich"; POSTGRES_INITDB_ARGS.value = "--data-checksums"; PGDATA.value = "/pgdata/data"; }; volumeMounts = [{ name = "data"; mountPath = "/pgdata"; }]; }; }; }; }; }; services = { server.spec = { type = "LoadBalancer"; loadBalancerIP = myLib.globals.immichIPv4; selector = { app = "immich"; component = "server"; }; ports.web = { port = 80; targetPort = "web"; }; }; redis.spec = { selector = { app = "immich"; component = "redis"; }; ports.redis = { port = 6379; targetPort = "redis"; }; }; ml.spec = { selector = { app = "immich"; component = "machine-learning"; }; ports.ml = { port = 80; targetPort = "ml"; }; }; postgres.spec = { selector = { app = "immich"; component = "database"; }; ports.postgres = { port = 5432; targetPort = "postgres"; }; }; }; persistentVolumeClaims.cache.spec = { accessModes = [ "ReadWriteOnce" ]; resources.requests.storage = "5Gi"; }; }; lab = { tailscaleIngresses.tailscale = { host = "immich"; service.name = "server"; }; longhorn.persistentVolumeClaim = { data = { volumeName = "immich"; storage = "50Gi"; }; database = { volumeName = "immich-db"; storage = "5Gi"; }; }; }; }