From 709a2d076c7b8e0ee67cb8b0ef05dd9d574f4b2b Mon Sep 17 00:00:00 2001 From: "azykov@mail.ru" Date: Fri, 21 Aug 2026 15:23:58 +0300 Subject: [PATCH] immich --- clusters/base/apps/immich/helmrelease-ml.yaml | 50 +++++++++++ .../apps/immich/helmrelease-postgres.yaml | 65 +++++++++++++++ .../base/apps/immich/helmrelease-redis.yaml | 33 ++++++++ .../base/apps/immich/helmrelease-server.yaml | 82 +++++++++++++++++++ clusters/base/apps/immich/helmrepository.yaml | 10 +++ clusters/base/apps/immich/kustomization.yaml | 9 ++ clusters/base/apps/immich/secret.enc.yaml | 22 +++++ clusters/base/namespaces/photo.yaml | 4 + clusters/home/apps/immich.yaml | 21 +++++ clusters/home/apps/kustomization.yaml | 3 +- clusters/home/namespaces/kustomization.yaml | 1 + 11 files changed, 299 insertions(+), 1 deletion(-) create mode 100644 clusters/base/apps/immich/helmrelease-ml.yaml create mode 100644 clusters/base/apps/immich/helmrelease-postgres.yaml create mode 100644 clusters/base/apps/immich/helmrelease-redis.yaml create mode 100644 clusters/base/apps/immich/helmrelease-server.yaml create mode 100644 clusters/base/apps/immich/helmrepository.yaml create mode 100644 clusters/base/apps/immich/kustomization.yaml create mode 100644 clusters/base/apps/immich/secret.enc.yaml create mode 100644 clusters/base/namespaces/photo.yaml create mode 100644 clusters/home/apps/immich.yaml diff --git a/clusters/base/apps/immich/helmrelease-ml.yaml b/clusters/base/apps/immich/helmrelease-ml.yaml new file mode 100644 index 0000000..db7a0a8 --- /dev/null +++ b/clusters/base/apps/immich/helmrelease-ml.yaml @@ -0,0 +1,50 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: immich-ml + namespace: photo +spec: + interval: 30m + chartRef: + kind: OCIRepository + name: immich + driftDetection: + mode: enabled + values: + controllers: + ml: + containers: + app: + # CPU-only: hardware-accelerated tags (-openvino, -cuda, etc) + # need specific host devices (e.g. /dev/dri) that aren't set up + # on these nodes. Switch tags later if that changes. + image: + repository: ghcr.io/immich-app/immich-machine-learning + tag: release + env: + TZ: Europe/Moscow + resources: + requests: + cpu: 500m + memory: 512Mi + limits: + memory: 4Gi + + service: + app: + controller: ml + ports: + http: + port: 3003 + + persistence: + # caches downloaded ML models so they survive pod restarts instead of + # re-downloading (a few hundred MB) every time. + cache: + type: persistentVolumeClaim + accessMode: ReadWriteOnce + size: 10Gi + storageClass: longhorn-single-replica + retain: true + globalMounts: + - path: /cache diff --git a/clusters/base/apps/immich/helmrelease-postgres.yaml b/clusters/base/apps/immich/helmrelease-postgres.yaml new file mode 100644 index 0000000..02e2e66 --- /dev/null +++ b/clusters/base/apps/immich/helmrelease-postgres.yaml @@ -0,0 +1,65 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: immich-postgres + namespace: photo +spec: + interval: 30m + chartRef: + kind: OCIRepository + name: immich + driftDetection: + mode: enabled + values: + controllers: + postgres: + containers: + app: + # immich requires this specific image - it bundles the + # vectorchord/pgvecto.rs extensions immich's DB schema depends + # on; a plain postgres image will not work. + image: + repository: ghcr.io/immich-app/postgres + tag: 14-vectorchord0.4.3-pgvectors0.2.0 + env: + TZ: Europe/Moscow + POSTGRES_USER: postgres + POSTGRES_DB: immich + POSTGRES_INITDB_ARGS: "--data-checksums" + POSTGRES_PASSWORD: + valueFrom: + secretKeyRef: + name: immich-secrets + key: DB_PASSWORD + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + memory: 2Gi + + service: + app: + controller: postgres + ports: + postgres: + port: 5432 + + persistence: + data: + type: persistentVolumeClaim + accessMode: ReadWriteOnce + size: 10Gi + storageClass: longhorn + retain: true + globalMounts: + - path: /var/lib/postgresql/data + # postgres' parallel query workers need real shared memory, not the + # default 64Mi container tmpfs - matches shm_size: 128mb in the + # original docker-compose. + dshm: + type: emptyDir + medium: Memory + sizeLimit: 128Mi + globalMounts: + - path: /dev/shm diff --git a/clusters/base/apps/immich/helmrelease-redis.yaml b/clusters/base/apps/immich/helmrelease-redis.yaml new file mode 100644 index 0000000..62c18d6 --- /dev/null +++ b/clusters/base/apps/immich/helmrelease-redis.yaml @@ -0,0 +1,33 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: immich-redis + namespace: photo +spec: + interval: 30m + chartRef: + kind: OCIRepository + name: immich + driftDetection: + mode: enabled + values: + controllers: + redis: + containers: + app: + image: + repository: docker.io/valkey/valkey + tag: "9" + resources: + requests: + cpu: 20m + memory: 32Mi + limits: + memory: 256Mi + + service: + app: + controller: redis + ports: + redis: + port: 6379 diff --git a/clusters/base/apps/immich/helmrelease-server.yaml b/clusters/base/apps/immich/helmrelease-server.yaml new file mode 100644 index 0000000..2ca28e1 --- /dev/null +++ b/clusters/base/apps/immich/helmrelease-server.yaml @@ -0,0 +1,82 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: immich-server + namespace: photo +spec: + interval: 30m + chartRef: + kind: OCIRepository + name: immich + driftDetection: + mode: enabled + values: + controllers: + server: + containers: + app: + image: + repository: ghcr.io/immich-app/immich-server + tag: release + env: + TZ: Europe/Moscow + DB_HOSTNAME: immich-postgres + DB_PORT: "5432" + DB_USERNAME: postgres + DB_DATABASE_NAME: immich + DB_PASSWORD: + valueFrom: + secretKeyRef: + name: immich-secrets + key: DB_PASSWORD + REDIS_HOSTNAME: immich-redis + REDIS_PORT: "6379" + IMMICH_MACHINE_LEARNING_URL: http://immich-ml:3003 + probes: + liveness: + enabled: true + readiness: + enabled: true + resources: + requests: + cpu: 200m + memory: 512Mi + limits: + memory: 4Gi + + service: + app: + controller: server + ports: + http: + port: 2283 + + ingress: + app: + className: traefik + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + hosts: + - host: photo.aggtaa.com + paths: + - path: / + pathType: Prefix + service: + identifier: app + port: http + tls: + - secretName: immich-tls + hosts: + - photo.aggtaa.com + + persistence: + # brand new, dedicated library - deliberately not reusing the old + # docker-compose install's NAS data, and not nfs-photo either. + library: + type: persistentVolumeClaim + accessMode: ReadWriteOnce + size: 100Gi + storageClass: longhorn-single-replica + retain: true + globalMounts: + - path: /data diff --git a/clusters/base/apps/immich/helmrepository.yaml b/clusters/base/apps/immich/helmrepository.yaml new file mode 100644 index 0000000..e0d75b1 --- /dev/null +++ b/clusters/base/apps/immich/helmrepository.yaml @@ -0,0 +1,10 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: OCIRepository +metadata: + name: immich + namespace: photo +spec: + interval: 1h + url: oci://ghcr.io/bjw-s-labs/helm/app-template + ref: + tag: "5.0.1" diff --git a/clusters/base/apps/immich/kustomization.yaml b/clusters/base/apps/immich/kustomization.yaml new file mode 100644 index 0000000..d205c70 --- /dev/null +++ b/clusters/base/apps/immich/kustomization.yaml @@ -0,0 +1,9 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - helmrepository.yaml + - secret.enc.yaml + - helmrelease-postgres.yaml + - helmrelease-redis.yaml + - helmrelease-ml.yaml + - helmrelease-server.yaml diff --git a/clusters/base/apps/immich/secret.enc.yaml b/clusters/base/apps/immich/secret.enc.yaml new file mode 100644 index 0000000..49a36bd --- /dev/null +++ b/clusters/base/apps/immich/secret.enc.yaml @@ -0,0 +1,22 @@ +apiVersion: v1 +kind: Secret +metadata: + name: immich-secrets + namespace: photo +stringData: + DB_PASSWORD: ENC[AES256_GCM,data:+bJ/+NEQCT3ZEqjnkzep4OsbLkJ9gyLZmGxCpoww2Wo=,iv:n1sLYgLl3zNZBdjMBhIrbSv/qHJFQ/nvZfBknFAUdug=,tag:DFnoc5K6XvHngVIrgJlM6Q==,type:str] +sops: + age: + - recipient: age14x4jjs2fwdgw28g2pkr6jyj2yzmwc544xwmaaglrxwz5e99seutqtr8jv5 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpNVpqUGJFMVhoMXdwa0FC + d20yRWpjVHd4UFJWOTNNUWViNUNuWmFncVcwCi9nRGhUY1JYMXhTa05MaVQ2a0Q1 + L0E2TTZDN25MUGdQM3ViT2JlVHNtc3MKLS0tIFRsMDVzTEdxUjNtMW1zaVpJZXlR + bVl6UXlLU0NRK2txOFpYTUJIQjJhVXcKLUeTuGJZZtC5zY2I8QjLS8G2zcjneUz8 + klo8dqrnrJBwmUPLV20f9GVPYUsbKYuj+kca30vqUE9jhXitP7uKjg== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-08-21T12:23:20Z" + mac: ENC[AES256_GCM,data:vGSUhl73AIQr1Ld1SHc+i4GpvOc0b0j8Vx9DmoRDjNs17TQSfmfulEZwIua12P5DHIz36P9yqggHfSyyrrEoMjfaUSTIDxCIGGvsfTl4vBt9Vis0e2gALaHtAgWZwxr5QMe+OP1tkXOZoX9E8VcoBq1ULvbIjqsPs2uxPVKsEWk=,iv:1exDUqurlFdBt1eZYWWMlkar75HbTLZ6RZelC0RsYcU=,tag:A0IhJHjVum2HBT5RwHo5qg==,type:str] + encrypted_regex: ^(data|stringData)$ + version: 3.11.0 diff --git a/clusters/base/namespaces/photo.yaml b/clusters/base/namespaces/photo.yaml new file mode 100644 index 0000000..9898f73 --- /dev/null +++ b/clusters/base/namespaces/photo.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: photo diff --git a/clusters/home/apps/immich.yaml b/clusters/home/apps/immich.yaml new file mode 100644 index 0000000..73c5cb2 --- /dev/null +++ b/clusters/home/apps/immich.yaml @@ -0,0 +1,21 @@ +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: immich + namespace: flux-system +spec: + interval: 10m + sourceRef: + kind: GitRepository + name: flux-system + path: ./clusters/base/apps/immich + prune: true + wait: true + dependsOn: + - name: namespaces + - name: infra + retryInterval: 5s + decryption: + provider: sops + secretRef: + name: sops-age diff --git a/clusters/home/apps/kustomization.yaml b/clusters/home/apps/kustomization.yaml index dcd3c1e..e33f142 100644 --- a/clusters/home/apps/kustomization.yaml +++ b/clusters/home/apps/kustomization.yaml @@ -15,4 +15,5 @@ resources: - infcloud.yaml - syncthing.yaml - nfs-photo.yaml - - photo-stats.yaml \ No newline at end of file + - photo-stats.yaml + - immich.yaml \ No newline at end of file diff --git a/clusters/home/namespaces/kustomization.yaml b/clusters/home/namespaces/kustomization.yaml index cb7ffb7..bed8eba 100644 --- a/clusters/home/namespaces/kustomization.yaml +++ b/clusters/home/namespaces/kustomization.yaml @@ -15,4 +15,5 @@ resources: - ../../base/namespaces/finance.yaml - ../../base/namespaces/nfs.yaml - ../../base/namespaces/syncthing.yaml + - ../../base/namespaces/photo.yaml - ../../base/namespaces/photo-stats.yaml