2026-08-25 18:21:28 -07:00
|
|
|
# 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
|
2026-08-25 18:49:09 -07:00
|
|
|
# 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;"
|
2026-08-25 18:50:09 -07:00
|
|
|
- "CREATE EXTENSION IF NOT EXISTS cube;"
|
|
|
|
|
- "CREATE EXTENSION IF NOT EXISTS earthdistance;"
|
2026-08-25 18:21:28 -07:00
|
|
|
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
|