diff --git a/README.md b/README.md index cddc9e6..8ff5002 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,7 @@ Currently, the applications being deployed like this are: - `paperless-ngx` - `syncthing` - `pihole` +- `immich` ## Known bugs diff --git a/flake-parts/kubenix.nix b/flake-parts/kubenix.nix index e844af8..f47fbf6 100644 --- a/flake-parts/kubenix.nix +++ b/flake-parts/kubenix.nix @@ -90,4 +90,6 @@ "${self}/kubenix-modules/syncthing.nix" "syncthing" "syncthing"; kubenix.pihole = mkDeployScriptAndManifest "${self}/kubenix-modules/pihole.nix" "pihole" "pihole"; + kubenix.immich = mkDeployScriptAndManifest + "${self}/kubenix-modules/immich.nix" "immich" "immich"; }) diff --git a/kubenix-modules/all.nix b/kubenix-modules/all.nix index 716cbd7..ca94a07 100644 --- a/kubenix-modules/all.nix +++ b/kubenix-modules/all.nix @@ -5,7 +5,6 @@ let ./bind9 ./dnsmasq.nix ./attic.nix - ./immich.nix # ./argo.nix # ./minecraft.nix ]; diff --git a/kubenix-modules/base.nix b/kubenix-modules/base.nix index f226da6..f19a1e3 100644 --- a/kubenix-modules/base.nix +++ b/kubenix-modules/base.nix @@ -73,6 +73,7 @@ paperless = { }; syncthing = { }; pihole = { }; + immich = { }; }; nodes = diff --git a/kubenix-modules/immich.nix b/kubenix-modules/immich.nix index b5ebfc2..87f7c5e 100644 --- a/kubenix-modules/immich.nix +++ b/kubenix-modules/immich.nix @@ -1,188 +1,162 @@ { kubernetes.resources = { deployments = { - immich-server = { - metadata.labels = { + immich.spec = { + selector.matchLabels = { app = "immich"; component = "server"; }; - spec = { - selector.matchLabels = { + strategy = { + type = "RollingUpdate"; + + rollingUpdate = { + maxSurge = 0; + maxUnavailable = 1; + }; + }; + + template = { + metadata.labels = { app = "immich"; component = "server"; }; - strategy = { - type = "RollingUpdate"; + spec = { + volumes.data.persistentVolumeClaim.claimName = "data"; - rollingUpdate = { - maxSurge = 0; - maxUnavailable = 1; - }; - }; + enableServiceLinks = false; - template = { - metadata.labels = { - app = "immich"; - component = "server"; - }; + containers.immich = { + image = "ghcr.io/immich-app/immich-server:v1.108.0"; + imagePullPolicy = "Always"; + ports.web.containerPort = 3001; - spec = { - volumes.data.persistentVolumeClaim.claimName = "immich"; - - containers.immich = { - image = "ghcr.io/immich-app/immich-server:v1.108.0"; - imagePullPolicy = "Always"; - ports.web.containerPort = 3001; - - env = { - TZ.value = "Europe/Amsterdam"; - REDIS_HOSTNAME.value = "immich-redis.default.svc.cluster.local"; - DB_HOSTNAME.value = "immich-postgres.default.svc.cluster.local"; - DB_USERNAME.value = "postgres"; - DB_PASSWORD.value = "ref+sops://secrets/kubernetes.yaml#/immich/databasePassword"; - DB_DATABASE_NAME.value = "immich"; - IMMICH_MACHINE_LEARNING_URL.value = "http://immich-ml.default.svc.cluster.local"; - }; - - volumeMounts = [{ - name = "data"; - mountPath = "/usr/src/app/upload"; - }]; + env = { + TZ.value = "Europe/Amsterdam"; + REDIS_HOSTNAME.value = "redis.immich.svc.cluster.local"; + DB_HOSTNAME.value = "postgres.immich.svc.cluster.local"; + DB_USERNAME.value = "postgres"; + DB_PASSWORD.value = "ref+sops://secrets/kubernetes.yaml#/immich/databasePassword"; + DB_DATABASE_NAME.value = "immich"; + IMMICH_MACHINE_LEARNING_URL.value = "http://ml.immich.svc.cluster.local"; }; + + volumeMounts = [{ + name = "data"; + mountPath = "/usr/src/app/upload"; + }]; }; }; }; }; - immich-ml = { - metadata.labels = { + ml.spec = { + selector.matchLabels = { app = "immich"; component = "machine-learning"; }; - spec = { - selector.matchLabels = { + template = { + metadata.labels = { app = "immich"; component = "machine-learning"; }; - template = { - metadata.labels = { - app = "immich"; - component = "machine-learning"; - }; + spec = { + volumes.cache.persistentVolumeClaim.claimName = "cache"; - spec = { - volumes.cache.persistentVolumeClaim.claimName = "immich-cache"; + containers.machine-learning = { + image = "ghcr.io/immich-app/immich-machine-learning:v1.108.0"; + imagePullPolicy = "Always"; + ports.ml.containerPort = 3003; + env.MACHINE_LEARNING_WORKER_TIMEOUT.value = "600"; - containers.machine-learning = { - image = "ghcr.io/immich-app/immich-machine-learning:v1.108.0"; - imagePullPolicy = "Always"; - ports.ml.containerPort = 3003; - env.MACHINE_LEARNING_WORKER_TIMEOUT.value = "600"; - - volumeMounts = [{ - name = "cache"; - mountPath = "/cache"; - }]; - }; + volumeMounts = [{ + name = "cache"; + mountPath = "/cache"; + }]; }; }; }; }; - immich-redis = { - metadata.labels = { + redis.spec = { + selector.matchLabels = { app = "immich"; component = "redis"; }; - spec = { - selector.matchLabels = { + strategy = { + type = "RollingUpdate"; + + rollingUpdate = { + maxSurge = 0; + maxUnavailable = 1; + }; + }; + + template = { + metadata.labels = { app = "immich"; component = "redis"; }; - strategy = { - type = "RollingUpdate"; - - rollingUpdate = { - maxSurge = 0; - maxUnavailable = 1; - }; - }; - - template = { - metadata.labels = { - app = "immich"; - component = "redis"; - }; - - spec = { - containers.redis = { - image = "docker.io/redis:6.2-alpine@sha256:d6c2911ac51b289db208767581a5d154544f2b2fe4914ea5056443f62dc6e900"; - ports.redis.containerPort = 6379; - imagePullPolicy = "Always"; - }; + spec = { + containers.redis = { + image = "docker.io/redis:6.2-alpine@sha256:d6c2911ac51b289db208767581a5d154544f2b2fe4914ea5056443f62dc6e900"; + ports.redis.containerPort = 6379; + imagePullPolicy = "Always"; }; }; }; }; - immich-database = { - metadata.labels = { + database.spec = { + selector.matchLabels = { app = "immich"; component = "database"; }; - spec = { - selector.matchLabels = { + strategy = { + type = "RollingUpdate"; + + rollingUpdate = { + maxSurge = 0; + maxUnavailable = 1; + }; + }; + + template = { + metadata.labels = { app = "immich"; component = "database"; }; - strategy = { - type = "RollingUpdate"; + spec = { + volumes.data.persistentVolumeClaim.claimName = "database"; - rollingUpdate = { - maxSurge = 0; - maxUnavailable = 1; - }; - }; + containers.postgres = { + image = "docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0"; + imagePullPolicy = "Always"; + command = [ "postgres" ]; + 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" ]; + ports.postgres.containerPort = 5432; + securityContext.runAsUser = 999; + securityContext.runAsGroup = 999; - template = { - metadata.labels = { - app = "immich"; - component = "database"; - }; - - spec = { - volumes.data.persistentVolumeClaim.claimName = "immich-db"; - - containers.postgres = { - image = "docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0"; - imagePullPolicy = "Always"; - command = [ "postgres" ]; - 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" ]; - ports.postgres.containerPort = 5432; - securityContext.runAsUser = 999; - securityContext.runAsGroup = 999; - - env = { - POSTGRES_PASSWORD.value = "ref+sops://secrets/kubernetes.yaml#/immich/databasePassword"; - POSTGRES_USER.value = "postgres"; - POSTGRES_DB.value = "immich"; - POSTGRES_INITDB_ARGS.value = "--data-checksums"; - PGDATA.value = "/pgdata/data"; - }; - - volumeMounts = [{ - name = "data"; - mountPath = "/pgdata"; - }]; + env = { + POSTGRES_PASSWORD.value = "ref+sops://secrets/kubernetes.yaml#/immich/databasePassword"; + POSTGRES_USER.value = "postgres"; + POSTGRES_DB.value = "immich"; + POSTGRES_INITDB_ARGS.value = "--data-checksums"; + PGDATA.value = "/pgdata/data"; }; + + volumeMounts = [{ + name = "data"; + mountPath = "/pgdata"; + }]; }; }; }; @@ -190,7 +164,7 @@ }; services = { - immich-server.spec = { + server.spec = { selector = { app = "immich"; component = "server"; @@ -202,7 +176,7 @@ }; }; - immich-redis.spec = { + redis.spec = { selector = { app = "immich"; component = "redis"; @@ -214,7 +188,7 @@ }; }; - immich-ml.spec = { + ml.spec = { selector = { app = "immich"; component = "machine-learning"; @@ -226,7 +200,7 @@ }; }; - immich-postgres.spec = { + postgres.spec = { selector = { app = "immich"; component = "database"; @@ -239,18 +213,32 @@ }; }; - persistentVolumeClaims.immich-cache.spec = { + persistentVolumeClaims.cache.spec = { accessModes = [ "ReadWriteOnce" ]; resources.requests.storage = "5Gi"; }; }; - lab.ingresses.immich-test = { - host = "immich.kun.is"; + lab = { + ingresses.immich = { + host = "immich.kun.is"; - service = { - name = "immich-server"; - portName = "web"; + service = { + name = "server"; + portName = "web"; + }; + }; + + longhorn.persistentVolumeClaim = { + data = { + volumeName = "immich"; + storage = "50Gi"; + }; + + database = { + volumeName = "immich-db"; + storage = "5Gi"; + }; }; }; } diff --git a/kubenix-modules/volumes.nix b/kubenix-modules/volumes.nix index 9ee626d..b1bedb3 100644 --- a/kubenix-modules/volumes.nix +++ b/kubenix-modules/volumes.nix @@ -34,8 +34,6 @@ bazarr.storage = "25Mi"; attic.storage = "15Gi"; attic-db.storage = "150Mi"; - immich.storage = "50Gi"; - immich-db.storage = "5Gi"; }; longhorn.persistentVolume = { @@ -55,6 +53,8 @@ syncthing.storage = "400Mi"; pihole-data.storage = "750Mi"; pihole-dnsmasq.storage = "16Mi"; + immich.storage = "50Gi"; + immich-db.storage = "5Gi"; }; nfsVolumes = {