From 5a9596c7d9a12b8edbe009022a0236fc2174a014 Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Wed, 13 May 2026 13:14:07 -0700 Subject: [PATCH] C2(migrate-immich-to-ringtail): impl add immich Deployments + bump GPU time-slicing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - argocd/manifests/immich-ringtail/: full port of the immich stack (server, ML, valkey, services, ingress, pvc-ml-cache) from argocd/manifests/immich/, with ringtail-specific tweaks: - deployment-ml: runtimeClassName=nvidia, nvidia.com/gpu:1 limit, -cuda image tag - deployment-valkey + kustomization: drop the registry.ops.eblu.me/blumeops/valkey mirror (arm64-only), use upstream docker.io/valkey/valkey:8.1.6 (multi-arch) - ingress-tailscale: tls.hosts=[photos-ringtail] for staging - argocd/apps/immich-ringtail.yaml: new ArgoCD app (manual sync, ringtail destination) - argocd/manifests/nvidia-device-plugin/time-slicing-config.yaml: bump replicas 2 -> 4 so the ringtail GPU can be shared by frigate + ollama + immich-ml The immich-db Secret in the immich namespace is created manually (matching minikube pattern) — see argocd/apps/immich-ringtail.yaml header for the procedure. Co-Authored-By: Claude Opus 4.7 (1M context) --- argocd/apps/immich-ringtail.yaml | 31 ++++++++ .../immich-ringtail/deployment-ml.yaml | 69 +++++++++++++++++ .../immich-ringtail/deployment-server.yaml | 74 +++++++++++++++++++ .../immich-ringtail/deployment-valkey.yaml | 42 +++++++++++ .../immich-ringtail/ingress-tailscale.yaml | 37 ++++++++++ .../immich-ringtail/kustomization.yaml | 22 +++++- .../immich-ringtail/pvc-ml-cache.yaml | 12 +++ .../manifests/immich-ringtail/service-ml.yaml | 14 ++++ .../immich-ringtail/service-valkey.yaml | 14 ++++ argocd/manifests/immich-ringtail/service.yaml | 14 ++++ .../time-slicing-config.yaml | 2 +- 11 files changed, 328 insertions(+), 3 deletions(-) create mode 100644 argocd/apps/immich-ringtail.yaml create mode 100644 argocd/manifests/immich-ringtail/deployment-ml.yaml create mode 100644 argocd/manifests/immich-ringtail/deployment-server.yaml create mode 100644 argocd/manifests/immich-ringtail/deployment-valkey.yaml create mode 100644 argocd/manifests/immich-ringtail/ingress-tailscale.yaml create mode 100644 argocd/manifests/immich-ringtail/pvc-ml-cache.yaml create mode 100644 argocd/manifests/immich-ringtail/service-ml.yaml create mode 100644 argocd/manifests/immich-ringtail/service-valkey.yaml create mode 100644 argocd/manifests/immich-ringtail/service.yaml diff --git a/argocd/apps/immich-ringtail.yaml b/argocd/apps/immich-ringtail.yaml new file mode 100644 index 0000000..c93cbee --- /dev/null +++ b/argocd/apps/immich-ringtail.yaml @@ -0,0 +1,31 @@ +# Immich on ringtail k3s. +# +# Staging deployment; the minikube `immich` app remains in parallel +# until cutover. See [[immich-cutover-and-decommission]] for the +# routing flip + minikube cleanup. +# +# Prerequisites: +# - cnpg-on-ringtail + databases-ringtail (postgres) +# - 1password-connect-ringtail + external-secrets-ringtail (not used +# by this app today — immich-db Secret is created manually, +# matching the minikube pattern) +# - The immich-db Secret in the immich namespace, holding the +# password for the `immich` postgres role (copied from the source +# immich-pg-app Secret at migration time). +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: immich-ringtail + namespace: argocd +spec: + project: default + source: + repoURL: ssh://forgejo@forge.ops.eblu.me:2222/eblume/blumeops.git + targetRevision: main + path: argocd/manifests/immich-ringtail + destination: + server: https://ringtail.tail8d86e.ts.net:6443 + namespace: immich + syncPolicy: + syncOptions: + - CreateNamespace=true diff --git a/argocd/manifests/immich-ringtail/deployment-ml.yaml b/argocd/manifests/immich-ringtail/deployment-ml.yaml new file mode 100644 index 0000000..5ea8035 --- /dev/null +++ b/argocd/manifests/immich-ringtail/deployment-ml.yaml @@ -0,0 +1,69 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: immich-machine-learning + namespace: immich +spec: + replicas: 1 + selector: + matchLabels: + app: immich + component: machine-learning + template: + metadata: + labels: + app: immich + component: machine-learning + spec: + runtimeClassName: nvidia + securityContext: + seccompProfile: + type: RuntimeDefault + containers: + - name: machine-learning + # ringtail uses the -cuda tag (set in kustomization.yaml) + # to take advantage of the RTX 4080 via the nvidia + # device plugin. Time-slicing is configured for 4 replicas + # so frigate + ollama + this pod can share. + image: ghcr.io/immich-app/immich-machine-learning:kustomized + ports: + - name: http + containerPort: 3003 + env: + - name: TZ + value: "America/Los_Angeles" + - name: TRANSFORMERS_CACHE + value: /cache + - name: HF_XET_CACHE + value: /cache/huggingface-xet + - name: MPLCONFIGDIR + value: /cache/matplotlib-config + volumeMounts: + - name: cache + mountPath: /cache + livenessProbe: + httpGet: + path: /ping + port: 3003 + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /ping + port: 3003 + initialDelaySeconds: 15 + periodSeconds: 10 + timeoutSeconds: 5 + resources: + requests: + memory: "512Mi" + cpu: "100m" + limits: + memory: "4Gi" + nvidia.com/gpu: "1" + volumes: + - name: cache + persistentVolumeClaim: + claimName: immich-ml-cache diff --git a/argocd/manifests/immich-ringtail/deployment-server.yaml b/argocd/manifests/immich-ringtail/deployment-server.yaml new file mode 100644 index 0000000..8ac7ab0 --- /dev/null +++ b/argocd/manifests/immich-ringtail/deployment-server.yaml @@ -0,0 +1,74 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: immich-server + namespace: immich +spec: + replicas: 1 + selector: + matchLabels: + app: immich + component: server + template: + metadata: + labels: + app: immich + component: server + spec: + securityContext: + seccompProfile: + type: RuntimeDefault + containers: + - name: server + image: ghcr.io/immich-app/immich-server:kustomized + ports: + - name: http + containerPort: 2283 + env: + - name: TZ + value: "America/Los_Angeles" + - name: DB_HOSTNAME + value: "immich-pg-rw.databases.svc.cluster.local" + - name: DB_PORT + value: "5432" + - name: DB_DATABASE_NAME + value: "immich" + - name: DB_USERNAME + value: "immich" + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: immich-db + key: password + - name: REDIS_HOSTNAME + value: immich-valkey + - name: IMMICH_MACHINE_LEARNING_URL + value: "http://immich-machine-learning:3003" + volumeMounts: + - name: library + mountPath: /usr/src/app/upload + livenessProbe: + httpGet: + path: /api/server/ping + port: 2283 + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /api/server/ping + port: 2283 + initialDelaySeconds: 15 + periodSeconds: 10 + timeoutSeconds: 5 + resources: + requests: + memory: "256Mi" + cpu: "100m" + limits: + memory: "2Gi" + volumes: + - name: library + persistentVolumeClaim: + claimName: immich-library diff --git a/argocd/manifests/immich-ringtail/deployment-valkey.yaml b/argocd/manifests/immich-ringtail/deployment-valkey.yaml new file mode 100644 index 0000000..1cf3346 --- /dev/null +++ b/argocd/manifests/immich-ringtail/deployment-valkey.yaml @@ -0,0 +1,42 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: immich-valkey + namespace: immich +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: immich + component: valkey + template: + metadata: + labels: + app: immich + component: valkey + spec: + securityContext: + seccompProfile: + type: RuntimeDefault + containers: + - name: valkey + image: docker.io/valkey/valkey:kustomized + ports: + - name: redis + containerPort: 6379 + volumeMounts: + - name: data + mountPath: /data + resources: + requests: + memory: "64Mi" + cpu: "25m" + limits: + memory: "256Mi" + volumes: + - name: data + emptyDir: + sizeLimit: 1Gi diff --git a/argocd/manifests/immich-ringtail/ingress-tailscale.yaml b/argocd/manifests/immich-ringtail/ingress-tailscale.yaml new file mode 100644 index 0000000..d12ab6d --- /dev/null +++ b/argocd/manifests/immich-ringtail/ingress-tailscale.yaml @@ -0,0 +1,37 @@ +# Tailscale ProxyGroup Ingress for Immich on ringtail. +# +# Staging hostname: photos-ringtail.tail8d86e.ts.net +# The minikube ingress claims the "photos" Tailscale device name. +# Tailscale enforces uniqueness across the tailnet, so this ingress +# uses photos-ringtail until the minikube ingress is torn down at +# cutover. See [[immich-cutover-and-decommission]] for the rename. +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: immich-tailscale + namespace: immich + annotations: + tailscale.com/funnel: "false" + tailscale.com/proxy-group: "ingress" + gethomepage.dev/enabled: "true" + gethomepage.dev/name: "Immich" + gethomepage.dev/group: "Content" + gethomepage.dev/icon: "immich.png" + gethomepage.dev/description: "Photo management" + gethomepage.dev/href: "https://photos.ops.eblu.me" + gethomepage.dev/pod-selector: "app=immich,component=server" +spec: + ingressClassName: tailscale + rules: + - http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: immich-server + port: + number: 2283 + tls: + - hosts: + - photos-ringtail diff --git a/argocd/manifests/immich-ringtail/kustomization.yaml b/argocd/manifests/immich-ringtail/kustomization.yaml index 583757b..c1f639e 100644 --- a/argocd/manifests/immich-ringtail/kustomization.yaml +++ b/argocd/manifests/immich-ringtail/kustomization.yaml @@ -3,8 +3,26 @@ kind: Kustomization namespace: immich -# Storage scaffolding for the ringtail-side Immich deployment. -# The Deployments/Services/Ingress land in immich-app-on-ringtail. resources: + - deployment-server.yaml + - deployment-ml.yaml + - deployment-valkey.yaml + - service.yaml + - service-ml.yaml + - service-valkey.yaml + - pvc-ml-cache.yaml - pv-nfs.yaml - pvc.yaml + - ingress-tailscale.yaml + +images: + - name: ghcr.io/immich-app/immich-server + newTag: v2.6.3 + - name: ghcr.io/immich-app/immich-machine-learning + # CUDA variant of the same release — ringtail has an RTX 4080 + newTag: v2.6.3-cuda + # Using upstream multi-arch valkey image directly; the + # registry.ops.eblu.me/blumeops/valkey mirror is arm64-only (built + # on indri) and would crashloop on ringtail. + - name: docker.io/valkey/valkey + newTag: "8.1.6" diff --git a/argocd/manifests/immich-ringtail/pvc-ml-cache.yaml b/argocd/manifests/immich-ringtail/pvc-ml-cache.yaml new file mode 100644 index 0000000..1e5a3d6 --- /dev/null +++ b/argocd/manifests/immich-ringtail/pvc-ml-cache.yaml @@ -0,0 +1,12 @@ +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: immich-ml-cache + namespace: immich +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi diff --git a/argocd/manifests/immich-ringtail/service-ml.yaml b/argocd/manifests/immich-ringtail/service-ml.yaml new file mode 100644 index 0000000..9bb935a --- /dev/null +++ b/argocd/manifests/immich-ringtail/service-ml.yaml @@ -0,0 +1,14 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: immich-machine-learning + namespace: immich +spec: + selector: + app: immich + component: machine-learning + ports: + - name: http + port: 3003 + targetPort: 3003 diff --git a/argocd/manifests/immich-ringtail/service-valkey.yaml b/argocd/manifests/immich-ringtail/service-valkey.yaml new file mode 100644 index 0000000..eb42d3b --- /dev/null +++ b/argocd/manifests/immich-ringtail/service-valkey.yaml @@ -0,0 +1,14 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: immich-valkey + namespace: immich +spec: + selector: + app: immich + component: valkey + ports: + - name: redis + port: 6379 + targetPort: 6379 diff --git a/argocd/manifests/immich-ringtail/service.yaml b/argocd/manifests/immich-ringtail/service.yaml new file mode 100644 index 0000000..d35410f --- /dev/null +++ b/argocd/manifests/immich-ringtail/service.yaml @@ -0,0 +1,14 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: immich-server + namespace: immich +spec: + selector: + app: immich + component: server + ports: + - name: http + port: 2283 + targetPort: 2283 diff --git a/argocd/manifests/nvidia-device-plugin/time-slicing-config.yaml b/argocd/manifests/nvidia-device-plugin/time-slicing-config.yaml index dee2fd7..100e7a9 100644 --- a/argocd/manifests/nvidia-device-plugin/time-slicing-config.yaml +++ b/argocd/manifests/nvidia-device-plugin/time-slicing-config.yaml @@ -11,4 +11,4 @@ data: timeSlicing: resources: - name: nvidia.com/gpu - replicas: 2 + replicas: 4