From 9cee20045f0be25a7715b9252049bbd42958b992 Mon Sep 17 00:00:00 2001 From: Jarno Rankinen Date: Tue, 11 Jun 2024 15:53:39 +0300 Subject: [PATCH 1/4] Single pod alternative pod YAML definition --- alternative/immich-pod.yaml | 162 ++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 alternative/immich-pod.yaml diff --git a/alternative/immich-pod.yaml b/alternative/immich-pod.yaml new file mode 100644 index 0000000..96f31b5 --- /dev/null +++ b/alternative/immich-pod.yaml @@ -0,0 +1,162 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: immich-config +data: + TZ: Etc/UTC + NODE_ENV: production + # LOG_LEVEL: verbose, debug, warn, error + LOG_LEVEL: warn + #IMMICH_MEDIA_LOCATION: "./upload" + #IMMICH_CONFIG_FILE: + #IMMICH_WEB_ROOT: + #IMMICH_REVERSE_GEOCODING_ROOT: + #HOST: 0.0.0.0 + #SERVER_PORT: 3001 + #MICROSERVICES_PORT: 3002 + #MACHINE_LEARNING_HOST: 0.0.0.0 + #MACHINE_LEARNING_PORT: 3003 + #DB_URL: + DB_HOSTNAME: localhost + DB_PORT: 5432 + DB_USERNAME: immich + DB_PASSWORD: Your-Secret-Postgres-Password + DB_DATABASE_NAME: immich + REDIS_HOST: 127.0.0.1 + REDIS_PORT: 6379 + #REDIS_URL: + #REDIS_USERNAME: + #REDIS_PASSWORD: +--- +apiVersion: v1 +kind: Pod +metadata: + name: immich + labels: + app: immich + annotations: +spec: + + ## Volume definitions, set paths to stored data here + volumes: + - hostPath: + ## Equivalent of UPLOAD_LOCATION in docker-compose + path: /path/to/immich/data/ + type: Directory + name: immich-data-host + - hostPath: + path: /path/to/immich/model-cache/ + type: Directory + name: immich-model-cache-host + - name: immich-psql + persistentVolumeClaim: + claimName: immich-psql + - hostPath: + path: /path/to/immich/redis + type: Directory + name: immich-redis-host + + ## Container definitions + containers: + - name: server + image: ghcr.io/immich-app/immich-server:v1.105.1 + resource: {} + securityContext: + capabilities: + drop: + - CAP_MKNOD + - CAP_NET_RAW + - CAP_AUDIT_WRITE + args: + - start.sh + - immich + volumeMounts: + - mountPath: /usr/src/app/upload + name: immich-data-host + ports: + ## Change hostPort here + - containerPort: 3001 + hostPort: 3001 + envFrom: + - configMapRef: + name: immich-config + optional: false + + - name: microservices + image: ghcr.io/immich-app/immich-server:v1.105.1 + args: + - start.sh + - microservices + envFrom: + - configMapRef: + name: immich-config + optional: false + volumeMounts: + - mountPath: /usr/src/app/upload + name: immich-data-host + + - name: machine-learning + args: + - ./start.sh + image: ghcr.io/immich-app/immich-machine-learning:v1.105.1 + volumeMounts: + - mountPath: /cache + name: immich-model-cache-host + envFrom: + - configMapRef: + name: immich-config + optional: false + + - name: psql + image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0 + resource: {} + securityContext: + capabilities: + drop: + - CAP_MKNOD + - CAP_NET_RAW + - CAP_AUDIT_WRITE + volumeMounts: + - mountPath: /var/lib/postgresql/data + name: immich-psql + env: + - name: POSTGRES_USER + valueFrom: + configMapKeyRef: + name: immich-config + key: DB_USERNAME + - name: POSTGRES_PASSWORD + valueFrom: + configMapKeyRef: + name: immich-config + key: DB_PASSWORD + - name: POSTGRES_DB + valueFrom: + configMapKeyRef: + name: immich-config + key: DB_DATABASE_NAME + - name: POSTGRES_INITDB_ARGS + value: "--data-checksums" + args: ["-c" ,"shared_preload_libraries=vectors.so", "-c", 'search_path="$$user", public, vectors', "-c", "logging_collector=on", "-c", "max_wal_size=2GB", "-c", "shared_buffers=512MB", "-c", "wal_compression=on"] + - name: redis + image: docker.io/library/redis:6.2-alpine + args: + - redis-server + - --save + - 60 + - 1 + - --loglevel + - warning + resources: {} + securityContext: + capabilities: + drop: + - CAP_MKNOD + - CAP_NET_RAW + - CAP_AUDIT_WRITE + volumeMounts: + - mountPath: /data + name: immich-redis-host + + restartPolicy: Always +status: {} \ No newline at end of file From b8d275c1d3ff95e4452c2b53067a0462a9460c24 Mon Sep 17 00:00:00 2001 From: Jarno Rankinen Date: Tue, 11 Jun 2024 16:41:58 +0300 Subject: [PATCH 2/4] Quadlet kube file and separate configMap --- alternative/immich-configMap.yaml | 29 +++++++++++++++++++++++++++ alternative/immich-pod.yaml | 33 ------------------------------- alternative/immich.kube | 7 +++++++ 3 files changed, 36 insertions(+), 33 deletions(-) create mode 100644 alternative/immich-configMap.yaml create mode 100644 alternative/immich.kube diff --git a/alternative/immich-configMap.yaml b/alternative/immich-configMap.yaml new file mode 100644 index 0000000..f9c2062 --- /dev/null +++ b/alternative/immich-configMap.yaml @@ -0,0 +1,29 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: immich-config +data: + TZ: Etc/UTC + NODE_ENV: production + # LOG_LEVEL: verbose, debug, warn, error + LOG_LEVEL: warn + #IMMICH_MEDIA_LOCATION: "./upload" + #IMMICH_CONFIG_FILE: + #IMMICH_WEB_ROOT: + #IMMICH_REVERSE_GEOCODING_ROOT: + #HOST: 0.0.0.0 + #SERVER_PORT: 3001 + #MICROSERVICES_PORT: 3002 + #MACHINE_LEARNING_HOST: 0.0.0.0 + #MACHINE_LEARNING_PORT: 3003 + #DB_URL: + DB_HOSTNAME: localhost + DB_PORT: 5432 + DB_USERNAME: immich + DB_PASSWORD: Your-Secret-Postgres-Password + DB_DATABASE_NAME: immich + REDIS_HOST: 127.0.0.1 + REDIS_PORT: 6379 + #REDIS_URL: + #REDIS_USERNAME: + #REDIS_PASSWORD: \ No newline at end of file diff --git a/alternative/immich-pod.yaml b/alternative/immich-pod.yaml index 96f31b5..30e9df7 100644 --- a/alternative/immich-pod.yaml +++ b/alternative/immich-pod.yaml @@ -1,32 +1,3 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: immich-config -data: - TZ: Etc/UTC - NODE_ENV: production - # LOG_LEVEL: verbose, debug, warn, error - LOG_LEVEL: warn - #IMMICH_MEDIA_LOCATION: "./upload" - #IMMICH_CONFIG_FILE: - #IMMICH_WEB_ROOT: - #IMMICH_REVERSE_GEOCODING_ROOT: - #HOST: 0.0.0.0 - #SERVER_PORT: 3001 - #MICROSERVICES_PORT: 3002 - #MACHINE_LEARNING_HOST: 0.0.0.0 - #MACHINE_LEARNING_PORT: 3003 - #DB_URL: - DB_HOSTNAME: localhost - DB_PORT: 5432 - DB_USERNAME: immich - DB_PASSWORD: Your-Secret-Postgres-Password - DB_DATABASE_NAME: immich - REDIS_HOST: 127.0.0.1 - REDIS_PORT: 6379 - #REDIS_URL: - #REDIS_USERNAME: - #REDIS_PASSWORD: --- apiVersion: v1 kind: Pod @@ -73,10 +44,6 @@ spec: volumeMounts: - mountPath: /usr/src/app/upload name: immich-data-host - ports: - ## Change hostPort here - - containerPort: 3001 - hostPort: 3001 envFrom: - configMapRef: name: immich-config diff --git a/alternative/immich.kube b/alternative/immich.kube new file mode 100644 index 0000000..545c727 --- /dev/null +++ b/alternative/immich.kube @@ -0,0 +1,7 @@ +[Install] +WantedBy=default.target + +[Kube] +Yaml=immich-pod.yaml +PublishPort=3001:3001 +ConfigMap=immich-configMap.yaml \ No newline at end of file From 01c0bd4f9d6d4c2ea7e808ee2d5f62d5011feca7 Mon Sep 17 00:00:00 2001 From: Jarno Rankinen Date: Tue, 11 Jun 2024 17:07:01 +0300 Subject: [PATCH 3/4] Update readme about single-pod deployment --- README.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/README.md b/README.md index aa35615..a5861fa 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,42 @@ the first start can fail if downloading the images takes more than the default s The containers should start on the next boot automatically. +# Alternative single-pod deployment + +## SELinux +On SELinux-enabled systems, the context of mapped host directories needs to be set manually. If all the mapped directories are under `/path/to/immich`, set the context with +``` +chcon -R -t container_file_t /path/to/immich +``` + +## rootful + +Copy the contents of the `alternative/` directory to `/etc/containers/systemd/` +or a subdirectory within, e.g. `/etc/containers/systemd/immich/` + +Edit the environment variables in `immich-configMap.yaml` according to the Immich upstream docker-compose instructions and change the published port in `immich.kube`. Edit host directory mappings in `immich-pod.yaml` + +Reload systemd units and start the service: +``` +systemctl daemon-reload` +systemctl start immich +``` + +## rootless + +Create and configure the user like above, username is `immich` in this example. Copy the contents of `alternative/` to `~/.config/containers/systemd/` or a subdirectory within. + +Edit `immich-configMap.yaml`, `immich-pod.yaml` and `immich.kube` like with the rootful deployment. + +Change ownership of the host directories to the created user. This user's UID will be mapped as root inside the containers. + +Start the user session, and the pod: +``` +systemctl start user@$(id -u immich)` +systemctl --user -M immich@.host start immich.service +``` + + # TODO - write a makefile or a justfile that insert the variables in the unit files maybe ? Right now it requires some copy and pasting. From d7ad96c8229b6bf18804eb4b65e3b9ac49b947f0 Mon Sep 17 00:00:00 2001 From: Jarno Rankinen Date: Sat, 7 Sep 2024 20:52:11 +0300 Subject: [PATCH 4/4] Updates according to discussion in #4 - Remove the separate microservices container (Immich v1.106.1+) - Update README.md with `enable-linger` method, improve wording - Move SELinux note to `Additional info` section - Added missing newlines to Quadlet files --- alternative/immich-configMap.yaml | 3 +- alternative/immich-pod.yaml | 64 ++++++++++++++----------------- alternative/immich.kube | 2 +- 3 files changed, 32 insertions(+), 37 deletions(-) diff --git a/alternative/immich-configMap.yaml b/alternative/immich-configMap.yaml index f9c2062..9e61645 100644 --- a/alternative/immich-configMap.yaml +++ b/alternative/immich-configMap.yaml @@ -26,4 +26,5 @@ data: REDIS_PORT: 6379 #REDIS_URL: #REDIS_USERNAME: - #REDIS_PASSWORD: \ No newline at end of file + #REDIS_PASSWORD: + \ No newline at end of file diff --git a/alternative/immich-pod.yaml b/alternative/immich-pod.yaml index 30e9df7..b812d5e 100644 --- a/alternative/immich-pod.yaml +++ b/alternative/immich-pod.yaml @@ -1,4 +1,3 @@ ---- apiVersion: v1 kind: Pod metadata: @@ -8,71 +7,65 @@ metadata: annotations: spec: - ## Volume definitions, set paths to stored data here + ## Volume definitions volumes: - - hostPath: + - name: immich-data-host + hostPath: ## Equivalent of UPLOAD_LOCATION in docker-compose - path: /path/to/immich/data/ + path: /path/to/immich/data type: Directory - name: immich-data-host - - hostPath: - path: /path/to/immich/model-cache/ + - name: immich-psql + hostPath: + path: /path/to/immich/model-cache type: Directory name: immich-model-cache-host - - name: immich-psql persistentVolumeClaim: claimName: immich-psql - - hostPath: + - name: immich-redis-host + hostPath: path: /path/to/immich/redis type: Directory - name: immich-redis-host ## Container definitions containers: + ## Starting from v1.106.1 the separate microservices + ## container is no longer necessary - name: server - image: ghcr.io/immich-app/immich-server:v1.105.1 - resource: {} + image: ghcr.io/immich-app/immich-server:v1.114.0 + envFrom: + - configMapRef: + name: immich-config + optional: false securityContext: capabilities: drop: - CAP_MKNOD - CAP_NET_RAW - CAP_AUDIT_WRITE - args: - - start.sh - - immich volumeMounts: - mountPath: /usr/src/app/upload name: immich-data-host - envFrom: - - configMapRef: - name: immich-config - optional: false + - mountPath: /nextcloud/nc-user + name: nextcloud-nc-user + readOnly: true - - name: microservices - image: ghcr.io/immich-app/immich-server:v1.105.1 - args: - - start.sh - - microservices + - name: machine-learning + image: ghcr.io/immich-app/immich-machine-learning:v1.114.0 envFrom: - configMapRef: name: immich-config optional: false + securityContext: + capabilities: + drop: + - CAP_MKNOD + - CAP_NET_RAW + - CAP_AUDIT_WRITE volumeMounts: - mountPath: /usr/src/app/upload name: immich-data-host - - - name: machine-learning - args: - - ./start.sh - image: ghcr.io/immich-app/immich-machine-learning:v1.105.1 - volumeMounts: - mountPath: /cache name: immich-model-cache-host - envFrom: - - configMapRef: - name: immich-config - optional: false - name: psql image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0 @@ -105,6 +98,7 @@ spec: - name: POSTGRES_INITDB_ARGS value: "--data-checksums" args: ["-c" ,"shared_preload_libraries=vectors.so", "-c", 'search_path="$$user", public, vectors', "-c", "logging_collector=on", "-c", "max_wal_size=2GB", "-c", "shared_buffers=512MB", "-c", "wal_compression=on"] + - name: redis image: docker.io/library/redis:6.2-alpine args: @@ -126,4 +120,4 @@ spec: name: immich-redis-host restartPolicy: Always -status: {} \ No newline at end of file +status: {} diff --git a/alternative/immich.kube b/alternative/immich.kube index 545c727..f7722a2 100644 --- a/alternative/immich.kube +++ b/alternative/immich.kube @@ -4,4 +4,4 @@ WantedBy=default.target [Kube] Yaml=immich-pod.yaml PublishPort=3001:3001 -ConfigMap=immich-configMap.yaml \ No newline at end of file +ConfigMap=immich-configMap.yaml