# Dedicated CNPG Postgres for Immich. Same recipe as paperless-db/authentik-db # (2 instances, default longhorn storage class) except the operand is # PostgreSQL 18, not 16.2 - the official CNPG pgvector extension image # (ghcr.io/cloudnative-pg/pgvector) is only published for pg18, no pg16 tags # exist in that registry. Immich itself supports pg18 fine (immich-app's own # postgres image already ships 18-vectorchord builds). # # pgvector loaded via CNPG's ImageVolume extension mechanism (CNPG 1.27+, # k8s ImageVolume feature - both present here: operator is 1.30.0, cluster is # v1.36.1). No shared_preload_libraries needed - pgvector doesn't require # preload, just CREATE EXTENSION, which immich-server issues itself at # startup. Distro/pg-major must match between the operand image and the # extension image (both "18"+"trixie" here) - CNPG's own compatibility rule. apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: immich-db annotations: argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true spec: instances: 2 imageName: ghcr.io/cloudnative-pg/postgresql:18-minimal-trixie postgresql: extensions: - name: pgvector image: reference: ghcr.io/cloudnative-pg/pgvector:0.8.1-18-trixie bootstrap: initdb: database: immich owner: app encoding: UTF8 localeCollate: C localeCType: C # CREATE EXTENSION vector requires superuser (pgvector's control file # isn't marked trusted) and the "app" owner role isn't one # (enableSuperuserAccess: false, repo convention) - postInitApplicationSQL # runs as superuser during initdb, before the app ever connects. Only # fires on a fresh bootstrap; the live cluster already had this run # manually once (kubectl exec ... psql -U postgres -c 'CREATE EXTENSION'). postInitApplicationSQL: - "CREATE EXTENSION IF NOT EXISTS vector;" - "CREATE EXTENSION IF NOT EXISTS cube;" - "CREATE EXTENSION IF NOT EXISTS earthdistance;" enableSuperuserAccess: false resources: requests: { memory: "512Mi", cpu: "250m" } limits: { memory: "2Gi", cpu: "1" } storage: size: 20Gi storageClass: longhorn affinity: podAntiAffinityType: preferred topologyKey: kubernetes.io/hostname tolerations: - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule