Immich
Prerequisites
This guide assumes you have the following prerequisites in place:
- Longhorn
- Zalando Postgres Operator
- Dragonfly Redis Operator
- Optionally, you can setup nvidia support or intel gpu support for better performance of Immich’s machine learning features.
Immich
Immich is a self-hosted photo and video backup solution. It provides a secure and private way to store and manage your media files.
Installation
Create the following directory structure for Immich:
immich/ βββ immich-db.yml βββ immich-ingress.yml βββ immich-ml.yml βββ immich-pvc.yml βββ immich-redis.yml βββ immich-secret.yml βββ immich-service.yml βββ immich.yml- Create this
Dockerfilefor custom postgres image:ARG PG_MAJOR=17 ARG VCHORD_VERSION=1.1.1 FROM ghcr.io/zalando/spilo-17:4.0-p3 ARG PG_MAJOR ARG VCHORD_VERSION USER root RUN apt-get update && \ apt-get install -y --no-install-recommends \ postgresql-${PG_MAJOR}-pgvector && \ rm -rf /var/lib/apt/lists/* RUN set -eux; \ ARCH=$(dpkg --print-architecture); \ DEB_URL="https://github.com/tensorchord/VectorChord/releases/download/${VCHORD_VERSION}/postgresql-${PG_MAJOR}-vchord_${VCHORD_VERSION}-1_${ARCH}.deb"; \ curl -fsSL -o /tmp/vchord.deb "${DEB_URL}"; \ dpkg -i /tmp/vchord.deb; \ rm /tmp/vchord.deb USER postgres - Build and push to custom docker registry:
docker build -t registry.com/username/repo:version docker push registry.com/username/repo:version - Create the
immich-db.ymlfile:--- apiVersion: acid.zalan.do/v1 kind: postgresql metadata: name: immich-db-cluster namespace: media spec: teamId: prod numberOfInstances: 2 dockerImage: registry.com/username/repo:version postgresql: version: "17" parameters: shared_preload_libraries: "bg_mon,pg_stat_statements,pgextwlist,pg_auth_mon,pg_cron,pg_stat_kcache,vchord" extwlist.extensions: "btree_gin,btree_gist,citext,extra_window_functions,first_last_agg,hll,hstore,hypopg,intarray,ltree,pgcrypto,pgq,pgq_node,pg_trgm,postgres_fdw,roaringbitmap,tablefunc,uuid-ossp,vector,vchord,timescaledb,pg_partman" preparedDatabases: immich: defaultUsers: true extensions: vchord: public vector: public earthdistance: public cube: public pg_trgm: public unaccent: public uuid-ossp: public plpgsql: public schemas: public: {} secretNamespace: media volume: size: 5Gi storageClass: longhorn initContainers: - name: fix-permissions image: busybox command: - sh - -c - | chmod 2775 /home/postgres/pgdata chown 0:103 /home/postgres/pgdata mkdir -p /home/postgres/pgdata/pgroot chown -R 101:103 /home/postgres/pgdata/pgroot chmod 750 /home/postgres/pgdata/pgroot volumeMounts: - name: pgdata mountPath: /home/postgres/pgdata securityContext: runAsUser: 0
- Create this
Add the following content to
immich/immich-ingress.yml:--- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: immich-ingress namespace: media annotations: cert-manager.io/cluster-issuer: letsencrypt-cloudflare traefik.ingress.kubernetes.io/router.entrypoints: websecure spec: ingressClassName: traefik tls: - hosts: - immich.example.com secretName: immich-tls rules: - host: immich.example.com http: paths: - path: / pathType: Prefix backend: service: name: immich-service port: number: 2283Add the following content to
immich/immich-ml.yml:--- apiVersion: apps/v1 kind: Deployment metadata: name: immich-ml namespace: media spec: strategy: type: Recreate replicas: 1 selector: matchLabels: app: immich-ml template: metadata: labels: app: immich-ml spec: #runtimeClassName: nvidia # For Nvidia GPUs only containers: - name: immich-machine-learning #image: ghcr.io/immich-app/immich-machine-learning:v2.5.6-cuda # For NVIDIA GPUs, use the CUDA image #image: ghcr.io/immich-app/immich-machine-learning:v2.5.6-openvino # For Intel GPUs, use the OpenVINO image image: ghcr.io/immich-app/immich-machine-learning:v2.5.6 # For CPU-only, use the standard image ports: - containerPort: 3003 env: - name: REDIS_HOSTNAME value: "immich-redis-service" #- name: NVIDIA_VISIBLE_DEVICES # For NVIDIA GPUs only # value: "all" # For NVIDIA GPUs only #- name: MACHINE_LEARNING_DEVICE_IDS # For NVIDIA GPUs only # value: "0" # For NVIDIA GPUS only volumeMounts: - name: model-cache mountPath: /cache #- name: dri # For Intel GPUs only # mountPath: /dev/dri # For Intel GPUs only # For NVIDIA GPUs, uncomment the following lines to request GPU resources #resources: # requests: # nvidia.com/gpu: "1" # limits: # nvidia.com/gpu: "1" # For Intel GPUs, uncomment the following lines to request GPU resources #resources: # limits: # gpu.intel.com/i915: "1" # requests: # gpu.intel.com/i915: "1" volumes: - name: model-cache persistentVolumeClaim: claimName: immich-cache-longhorn #- name: dri # For Intel GPUs only # hostPath: # For Intel GPUs only # path: /dev/dri # For Intel GPUs onlyAdd the following content to
immich/immich-pvc.yml:--- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: immich-cache-longhorn namespace: media spec: accessModes: - ReadWriteOnce volumeMode: Filesystem resources: requests: storage: 10Gi storageClassName: longhorn --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: immich-pictures-pvc namespace: media spec: accessModes: - ReadWriteMany storageClassName: immich-pictures-pv resources: requests: storage: 100GiAdd the following content to
immich/immich-redis.yml:--- apiVersion: dragonflydb.io/v1alpha1 kind: Dragonfly metadata: name: immich-redis namespace: media spec: replicas: 3 resources: requests: cpu: 100m memory: 128Mi limits: cpu: 500m memory: 512Mi args: - --maxmemory=256mbAdd the following content to
immich/immich-service.yml:--- apiVersion: v1 kind: Service metadata: name: immich-service namespace: media spec: selector: app: immich-app ports: - port: 2283 targetPort: 2283 --- apiVersion: v1 kind: Service metadata: name: immich-machine-learning-service namespace: media spec: selector: app: immich-ml ports: - port: 3003 targetPort: 3003 --- apiVersion: v1 kind: Service metadata: name: immich-psql namespace: media spec: selector: app: immich-psql ports: - name: postgres port: 5432 targetPort: 5432 clusterIP: None --- apiVersion: v1 kind: Service metadata: name: immich-redis namespace: media spec: selector: app: immich-redis ports: - name: redis port: 6379 targetPort: 6379 clusterIP: NoneAdd the following content to
immich/immich.yml:--- apiVersion: apps/v1 kind: Deployment metadata: name: immich-app namespace: media spec: strategy: type: Recreate replicas: 1 selector: matchLabels: app: immich-app template: metadata: labels: app: immich-app spec: containers: - name: immich-server image: ghcr.io/immich-app/immich-server:v2.5.6 ports: - containerPort: 2283 env: - name: REDIS_HOSTNAME value: "immich-redis.media.svc.cluster.local" - name: DB_USERNAME value: "postgres" - name: DB_DATABASE_NAME value: "immich" - name: DB_HOSTNAME value: "immich-db-cluster.media.svc.cluster.local" - name: DB_PASSWORD valueFrom: secretKeyRef: name: postgres.immich-db-cluster.credentials.postgresql.acid.zalan.do key: password volumeMounts: - mountPath: /usr/src/app/upload name: pictures volumes: - name: pictures nfs: server: <nfs-server-ip> path: <nfs-export-path>Commit and push the changes to your Git repository. Flux will automatically deploy Immich to your Kubernetes cluster.