homelab/kubernetes: update immich database handling
All checks were successful
ci/woodpecker/push/demo-workflow Pipeline was successful

This commit is contained in:
2025-11-29 11:10:57 +02:00
parent db86c11611
commit cf23ad5a4f
5 changed files with 124 additions and 6 deletions

View File

@ -860,6 +860,8 @@ the k3s cluster. The Immich deployment uses the existing postgres database
for data storage. The Immich service is exposed via ingress and is accessible for data storage. The Immich service is exposed via ingress and is accessible
from the internet. from the internet.
## Database
To use the existing postgres database, first create a new user and database To use the existing postgres database, first create a new user and database
for Immich in the postgres database. for Immich in the postgres database.
@ -883,7 +885,19 @@ LC_CTYPE 'en_US.UTF-8';
CREATE EXTENSION vectors; CREATE EXTENSION vectors;
``` ```
Next, create or verify local disk for immich backup Currently, instead of Cloudnative-PG database, a single instance of postgres
statefulset with recommended postgres + extensions image from Immich is used.
```bash
source .env
envsubst < immich/database.yaml | kubectl apply -n immich -f -
```
## Persistant Storage for media
Next, create or verify local disk for immich backup. For my setup, I have a
dedicated server with a large disk that I want to use for immich media storage.
The disk is mounted at /media/immich via NFS.
```bash ```bash
ssh dockerhost ssh dockerhost
@ -1012,4 +1026,4 @@ using powerful search capabilities.
```bash ```bash
source .env source .env
envsubst < paperless-ngx/manifest.yaml | kubectl apply -f - envsubst < paperless-ngx/manifest.yaml | kubectl apply -f -
``` ```

View File

@ -0,0 +1,104 @@
apiVersion: v1
kind: Secret
metadata:
name: immich-postgres-secret
type: Opaque
stringData:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: "${IMMICH_DB_PASSWORD}"
POSTGRES_DB: "${IMMICH_DB_NAME}"
---
apiVersion: v1
kind: Service
metadata:
name: immich-postgres
labels:
app: immich-postgres
spec:
clusterIP: None # headless for StatefulSet stable DNS
selector:
app: immich-postgres
ports:
- port: 5432
name: postgres
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: immich-postgres
spec:
serviceName: immich-postgres
replicas: 1
selector:
matchLabels:
app: immich-postgres
template:
metadata:
labels:
app: immich-postgres
spec:
securityContext:
fsGroup: 999
containers:
- name: postgres
image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0
imagePullPolicy: IfNotPresent
securityContext:
runAsUser: 999
runAsGroup: 999
ports:
- containerPort: 5432
name: postgres
env:
- name: PGDATA
value: /var/lib/postgresql/data
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: immich-postgres-secret
key: POSTGRES_USER
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: immich-postgres-secret
key: POSTGRES_PASSWORD
- name: POSTGRES_DB
valueFrom:
secretKeyRef:
name: immich-postgres-secret
key: POSTGRES_DB
volumeMounts:
- name: data
mountPath: /var/lib/postgresql
readinessProbe:
exec:
command:
- sh
- -c
- pg_isready -U ${POSTGRES_USER}
initialDelaySeconds: 10
periodSeconds: 10
livenessProbe:
exec:
command:
- sh
- -c
- pg_isready -U ${POSTGRES_USER}
initialDelaySeconds: 30
periodSeconds: 30
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 1000m
memory: 2Gi
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: longhorn
resources:
requests:
storage: 20Gi

View File

@ -6,7 +6,7 @@
env: env:
REDIS_HOSTNAME: '{{ printf "%s-valkey" .Release.Name }}' REDIS_HOSTNAME: '{{ printf "%s-valkey" .Release.Name }}'
DB_HOSTNAME: immich-database-rw.immich.svc.cluster.local DB_HOSTNAME: immich-postgres-0.immich-postgres.immich.svc.cluster.local
DB_USERNAME: placeholder DB_USERNAME: placeholder
DB_DATABASE_NAME: immich DB_DATABASE_NAME: immich
# -- You should provide your own secret outside of this helm-chart and use `postgresql.global.postgresql.auth.existingSecret` to provide credentials to the postgresql instance # -- You should provide your own secret outside of this helm-chart and use `postgresql.global.postgresql.auth.existingSecret` to provide credentials to the postgresql instance

View File

@ -30,8 +30,8 @@ spec:
- name: barman-cloud.cloudnative-pg.io - name: barman-cloud.cloudnative-pg.io
isWALArchiver: true isWALArchiver: true
parameters: parameters:
barmanObjectName: immich-minio-store barmanObjectName: immich-garage-store
storage: storage:
storageClass: longhorn-2x storageClass: longhorn-2x
size: 5Gi size: 32Gi

View File

@ -6,7 +6,7 @@
env: env:
REDIS_HOSTNAME: '{{ printf "%s-valkey" .Release.Name }}' REDIS_HOSTNAME: '{{ printf "%s-valkey" .Release.Name }}'
DB_HOSTNAME: immich-database-rw.immich.svc.cluster.local DB_HOSTNAME: immich-postgres-0.immich-postgres.immich.svc.cluster.local
DB_USERNAME: placeholder DB_USERNAME: placeholder
DB_DATABASE_NAME: immich DB_DATABASE_NAME: immich
# -- You should provide your own secret outside of this helm-chart and use `postgresql.global.postgresql.auth.existingSecret` to provide credentials to the postgresql instance # -- You should provide your own secret outside of this helm-chart and use `postgresql.global.postgresql.auth.existingSecret` to provide credentials to the postgresql instance