--- apiVersion: v1 kind: Namespace metadata: name: immich-system --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: immich-postgres namespace: immich-system spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi storageClassName: longhorn --- apiVersion: apps/v1 kind: Deployment metadata: name: immich-postgres namespace: immich-system labels: app.kubernetes.io/instance: immich app.kubernetes.io/name: postgres spec: replicas: 1 strategy: type: Recreate selector: matchLabels: app.kubernetes.io/instance: immich app.kubernetes.io/name: postgres template: metadata: labels: app.kubernetes.io/instance: immich app.kubernetes.io/name: postgres annotations: match-regex.version-checker.io/postgres: '^\d+-vectorchord\d+\.\d+\.\d+$' spec: securityContext: fsGroup: 999 containers: - name: postgres image: ghcr.io/immich-app/postgres:16-vectorchord0.3.0 env: - name: POSTGRES_USER valueFrom: secretKeyRef: name: immich-db key: username - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: name: immich-db key: password - name: POSTGRES_DB value: immich - name: PGDATA value: /var/lib/postgresql/data/pgdata ports: - containerPort: 5432 name: postgres volumeMounts: - name: data mountPath: /var/lib/postgresql/data subPath: data resources: requests: cpu: 100m memory: 256Mi limits: cpu: 1 memory: 1Gi volumes: - name: data persistentVolumeClaim: claimName: immich-postgres --- apiVersion: v1 kind: Service metadata: name: immich-postgres namespace: immich-system spec: type: ClusterIP ports: - port: 5432 targetPort: postgres name: postgres selector: app.kubernetes.io/instance: immich app.kubernetes.io/name: postgres --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: immich-machine-learning labels: app.kubernetes.io/instance: immich app.kubernetes.io/name: machine-learning app.kubernetes.io/version: v2.5.5 namespace: immich-system spec: accessModes: - "ReadWriteOnce" resources: requests: storage: "10Gi" storageClassName: "longhorn" --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: immich-valkey labels: app.kubernetes.io/instance: immich app.kubernetes.io/name: valkey app.kubernetes.io/version: v2.5.5 namespace: immich-system spec: accessModes: - "ReadWriteOnce" resources: requests: storage: "1Gi" storageClassName: "longhorn" --- apiVersion: v1 kind: Service metadata: name: immich-machine-learning labels: app.kubernetes.io/instance: immich app.kubernetes.io/name: machine-learning app.kubernetes.io/service: immich-machine-learning app.kubernetes.io/version: v2.5.5 namespace: immich-system spec: type: ClusterIP ports: - port: 3003 targetPort: http protocol: TCP name: http selector: app.kubernetes.io/controller: main app.kubernetes.io/instance: immich app.kubernetes.io/name: machine-learning --- apiVersion: v1 kind: Service metadata: name: immich-server labels: app.kubernetes.io/instance: immich app.kubernetes.io/name: server app.kubernetes.io/service: immich-server app.kubernetes.io/version: v2.5.5 namespace: immich-system spec: type: ClusterIP ports: - port: 2283 targetPort: http protocol: TCP name: http selector: app.kubernetes.io/controller: main app.kubernetes.io/instance: immich app.kubernetes.io/name: server --- apiVersion: v1 kind: Service metadata: name: immich-valkey labels: app.kubernetes.io/instance: immich app.kubernetes.io/name: valkey app.kubernetes.io/service: immich-valkey app.kubernetes.io/version: v2.5.5 namespace: immich-system spec: type: ClusterIP ports: - port: 6379 targetPort: redis protocol: TCP name: redis selector: app.kubernetes.io/controller: main app.kubernetes.io/instance: immich app.kubernetes.io/name: valkey --- apiVersion: apps/v1 kind: Deployment metadata: name: immich-machine-learning labels: app.kubernetes.io/controller: main app.kubernetes.io/instance: immich app.kubernetes.io/name: machine-learning app.kubernetes.io/version: v2.5.5 namespace: immich-system spec: revisionHistoryLimit: 3 replicas: 1 strategy: type: Recreate selector: matchLabels: app.kubernetes.io/controller: main app.kubernetes.io/name: machine-learning app.kubernetes.io/instance: immich template: metadata: labels: app.kubernetes.io/controller: main app.kubernetes.io/instance: immich app.kubernetes.io/name: machine-learning spec: enableServiceLinks: false serviceAccountName: default automountServiceAccountToken: true hostIPC: false hostNetwork: false hostPID: false dnsPolicy: ClusterFirst containers: - env: - name: HF_XET_CACHE value: /cache/huggingface-xet - name: IMMICH_MACHINE_LEARNING_URL value: http://immich-machine-learning:3003 - name: MPLCONFIGDIR value: /cache/matplotlib-config - name: REDIS_HOSTNAME value: immich-valkey - name: TRANSFORMERS_CACHE value: /cache image: ghcr.io/immich-app/immich-machine-learning:v2.5.5 imagePullPolicy: IfNotPresent livenessProbe: failureThreshold: 3 httpGet: path: /ping port: http initialDelaySeconds: 0 periodSeconds: 10 timeoutSeconds: 1 name: main ports: - containerPort: 3003 name: http protocol: TCP readinessProbe: failureThreshold: 3 httpGet: path: /ping port: http initialDelaySeconds: 0 periodSeconds: 10 timeoutSeconds: 1 startupProbe: failureThreshold: 60 httpGet: path: /ping port: http initialDelaySeconds: 0 periodSeconds: 10 timeoutSeconds: 1 volumeMounts: - mountPath: /cache name: cache volumes: - name: cache persistentVolumeClaim: claimName: immich-machine-learning --- apiVersion: apps/v1 kind: Deployment metadata: name: immich-server labels: app.kubernetes.io/controller: main app.kubernetes.io/instance: immich app.kubernetes.io/name: server app.kubernetes.io/version: v2.5.5 namespace: immich-system spec: revisionHistoryLimit: 3 replicas: 1 strategy: type: Recreate selector: matchLabels: app.kubernetes.io/controller: main app.kubernetes.io/name: server app.kubernetes.io/instance: immich template: metadata: labels: app.kubernetes.io/controller: main app.kubernetes.io/instance: immich app.kubernetes.io/name: server spec: enableServiceLinks: false serviceAccountName: default automountServiceAccountToken: true hostIPC: false hostNetwork: false hostPID: false dnsPolicy: ClusterFirst containers: - env: - name: DB_HOSTNAME value: immich-postgres - name: DB_PORT value: "5432" - name: DB_DATABASE_NAME value: immich - name: DB_USERNAME valueFrom: secretKeyRef: name: immich-db key: username - name: DB_PASSWORD valueFrom: secretKeyRef: name: immich-db key: password - name: IMMICH_MACHINE_LEARNING_URL value: http://immich-machine-learning:3003 - name: REDIS_HOSTNAME value: immich-valkey image: ghcr.io/immich-app/immich-server:v2.5.5 imagePullPolicy: IfNotPresent livenessProbe: failureThreshold: 3 httpGet: path: /api/server/ping port: http initialDelaySeconds: 0 periodSeconds: 10 timeoutSeconds: 1 name: main ports: - containerPort: 2283 name: http protocol: TCP readinessProbe: failureThreshold: 3 httpGet: path: /api/server/ping port: http initialDelaySeconds: 0 periodSeconds: 10 timeoutSeconds: 1 startupProbe: failureThreshold: 30 httpGet: path: /api/server/ping port: http initialDelaySeconds: 0 periodSeconds: 10 timeoutSeconds: 1 volumeMounts: - mountPath: /data name: data volumes: - name: data hostPath: path: /mnt/4_hdd/data/immich type: Directory --- apiVersion: apps/v1 kind: Deployment metadata: name: immich-valkey labels: app.kubernetes.io/controller: main app.kubernetes.io/instance: immich app.kubernetes.io/name: valkey app.kubernetes.io/version: v2.5.5 namespace: immich-system spec: revisionHistoryLimit: 3 replicas: 1 strategy: type: Recreate selector: matchLabels: app.kubernetes.io/controller: main app.kubernetes.io/name: valkey app.kubernetes.io/instance: immich template: metadata: labels: app.kubernetes.io/controller: main app.kubernetes.io/instance: immich app.kubernetes.io/name: valkey spec: enableServiceLinks: false serviceAccountName: default automountServiceAccountToken: true hostIPC: false hostNetwork: false hostPID: false dnsPolicy: ClusterFirst containers: - env: - name: IMMICH_MACHINE_LEARNING_URL value: http://immich-machine-learning:3003 - name: REDIS_HOSTNAME value: immich-valkey image: docker.io/valkey/valkey:9.1-alpine@sha256:a35428eba9043cc0b79dbe54100f0c92784f2de00ad09b01182bfb1c5c83d1bd imagePullPolicy: IfNotPresent livenessProbe: exec: command: - sh - -c - valkey-cli ping | grep PONG failureThreshold: 3 initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 name: main ports: - containerPort: 6379 name: redis protocol: TCP readinessProbe: exec: command: - sh - -c - valkey-cli ping | grep PONG failureThreshold: 3 initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 5 startupProbe: exec: command: - sh - -c - valkey-cli ping | grep PONG failureThreshold: 30 initialDelaySeconds: 0 periodSeconds: 10 timeoutSeconds: 5 volumeMounts: - mountPath: /data name: data volumes: - name: data persistentVolumeClaim: claimName: immich-valkey --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: immich-server labels: app.kubernetes.io/instance: immich app.kubernetes.io/name: server app.kubernetes.io/version: v2.5.5 annotations: cert-manager.io/cluster-issuer: letsencrypt-prod external-dns.alpha.kubernetes.io/hostname: photos.dooplex.hu nginx.ingress.kubernetes.io/proxy-body-size: "0" nginx.ingress.kubernetes.io/ssl-redirect: "true" # GeoIP-based access control nginx.ingress.kubernetes.io/configuration-snippet: | # GeoIP-based access control for Immich # Allows Hungarian traffic everywhere, worldwide only for /share/* paths set $geo_allowed 0; # Allow private/local networks if ($remote_addr ~ "^192\.168\.") { set $geo_allowed 1; } if ($remote_addr ~ "^10\.") { set $geo_allowed 1; } # Allow all Hungarian traffic if ($geoip2_country_code = "HU") { set $geo_allowed 1; } # Public share paths if ($request_uri ~* "^/share") { set $geo_allowed 1; } # API endpoints needed for shares if ($request_uri ~* "^/api/shared-links") { set $geo_allowed 1; } if ($request_uri ~* "^/api/assets") { set $geo_allowed 1; } if ($request_uri ~* "^/api/albums") { set $geo_allowed 1; } if ($request_uri ~* "^/api/server") { set $geo_allowed 1; } if ($request_uri ~* "^/api/timeline") { set $geo_allowed 1; } if ($request_uri ~* "^/api/users/me") { set $geo_allowed 1; } # Static assets if ($request_uri ~* "^/_app/") { set $geo_allowed 1; } if ($request_uri ~* "\.(js|css|woff2?|ttf|svg|png|ico|jpg|jpeg|webp)$") { set $geo_allowed 1; } if ($geo_allowed = 0) { return 403 "Access restricted to Hungary"; } namespace: immich-system spec: ingressClassName: nginx-internal tls: - hosts: - "photos.dooplex.hu" secretName: "immich-tls" rules: - host: "photos.dooplex.hu" http: paths: - path: "/" pathType: Prefix backend: service: name: immich-server port: number: 2283 - host: "photos.home" http: paths: - path: "/" pathType: Prefix backend: service: name: immich-server port: number: 2283