From a10917b996c12387fdf81dced350df1da95aa946 Mon Sep 17 00:00:00 2001 From: Floris Feddema Date: Mon, 1 Jul 2024 22:49:34 +0200 Subject: [PATCH] immich: add product --- charts/immich/.helmignore | 23 +++++ charts/immich/Chart.yaml | 9 ++ charts/immich/README.md | 16 ++++ charts/immich/templates/_helpers.tpl | 21 +++++ .../immich/templates/database/database.yaml | 47 ++++++++++ .../templates/database/pod-monitor.yaml | 17 ++++ charts/immich/templates/ingress.yaml | 33 +++++++ .../machine-learning/deployment.yaml | 63 +++++++++++++ .../templates/machine-learning/service.yaml | 20 ++++ charts/immich/templates/pvc-library.yaml | 18 ++++ .../immich/templates/server/deployment.yaml | 93 +++++++++++++++++++ .../templates/server/service-metrics.yaml | 20 ++++ .../templates/server/service-monitor.yaml | 18 ++++ charts/immich/templates/server/service.yaml | 20 ++++ charts/immich/values.yaml | 71 ++++++++++++++ charts/infro/Chart.yaml | 2 +- charts/infro/templates/_helpers.tpl | 2 +- charts/infro/templates/deployment.yaml | 4 +- charts/infro/templates/secret.yaml | 2 +- 19 files changed, 494 insertions(+), 5 deletions(-) create mode 100644 charts/immich/.helmignore create mode 100644 charts/immich/Chart.yaml create mode 100644 charts/immich/README.md create mode 100644 charts/immich/templates/_helpers.tpl create mode 100644 charts/immich/templates/database/database.yaml create mode 100644 charts/immich/templates/database/pod-monitor.yaml create mode 100644 charts/immich/templates/ingress.yaml create mode 100644 charts/immich/templates/machine-learning/deployment.yaml create mode 100644 charts/immich/templates/machine-learning/service.yaml create mode 100644 charts/immich/templates/pvc-library.yaml create mode 100644 charts/immich/templates/server/deployment.yaml create mode 100644 charts/immich/templates/server/service-metrics.yaml create mode 100644 charts/immich/templates/server/service-monitor.yaml create mode 100644 charts/immich/templates/server/service.yaml create mode 100644 charts/immich/values.yaml diff --git a/charts/immich/.helmignore b/charts/immich/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/immich/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/immich/Chart.yaml b/charts/immich/Chart.yaml new file mode 100644 index 0000000..fd7477e --- /dev/null +++ b/charts/immich/Chart.yaml @@ -0,0 +1,9 @@ +apiVersion: v2 +name: immich +version: 1.0.0 + +dependencies: + - name: redis + version: 19.6.0 + repository: https://charts.bitnami.com/bitnami + condition: redis.enabled diff --git a/charts/immich/README.md b/charts/immich/README.md new file mode 100644 index 0000000..68c0396 --- /dev/null +++ b/charts/immich/README.md @@ -0,0 +1,16 @@ +# Immich + +## How to use + +Add repository by running: + +```bash +helm repo add k8s-at-our-home https://k8s-at-our-homes.github.io/helm-charts/ +helm install immich k8s-at-our-home/immich +``` + +Or get the chart from ghcr.io: + +```bash +helm install generic-device-plugin oci://ghcr.io/k8s-at-our-homes/helm-charts/immich +``` diff --git a/charts/immich/templates/_helpers.tpl b/charts/immich/templates/_helpers.tpl new file mode 100644 index 0000000..6c1d0e5 --- /dev/null +++ b/charts/immich/templates/_helpers.tpl @@ -0,0 +1,21 @@ +{{- define "common.name" -}} +{{- .Chart.Name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "common.fullname" -}} +{{- if contains .Chart.Name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} + +{{- define "chartName" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "common.labels" -}} +app.kubernetes.io/version: {{ .Chart.Version | quote }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +helm.sh/chart: {{ include "chartName" . }} +{{- end -}} diff --git a/charts/immich/templates/database/database.yaml b/charts/immich/templates/database/database.yaml new file mode 100644 index 0000000..a10fbda --- /dev/null +++ b/charts/immich/templates/database/database.yaml @@ -0,0 +1,47 @@ +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + name: {{ .Values.database.clusterName }} + labels: + app.kubernetes.io/name: {{ template "common.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "immich" + {{- include "common.labels" . | nindent 4 }} +spec: + instances: {{ .Values.database.replicas }} + imageName: {{ .Values.database.image.registry }}/{{ .Values.database.image.repository }}:{{ .Values.database.image.tag }} + + postgresql: + shared_preload_libraries: + - "vectors.so" + + logLevel: {{ .Values.database.logLevel }} + + bootstrap: + initdb: + postInitApplicationSQL: + - CREATE EXTENSION IF NOT EXISTS "vectors"; + - CREATE EXTENSION IF NOT EXISTS "cube"; + - CREATE EXTENSION IF NOT EXISTS "earthdistance"; + - ALTER SYSTEM SET search_path TO app, public, vectors; + - ALTER SCHEMA vectors OWNER TO app; + # run this via kubectl exec in database pod after the schema is created + #- \c app; GRANT SELECT ON TABLE pg_vector_index_stat TO app; + + storage: + size: {{ .Values.database.size }} + + {{ if .Values.database.backups.enabled }} + backup: + retentionPolicy: {{ .Values.database.backups.retention }} + barmanObjectStore: + destinationPath: {{ .Values.database.backups.path | quote }} + endpointURL: {{ .Values.database.backups.endpoint }} + s3Credentials: + accessKeyId: + name: {{ .Values.database.backups.secretName }} + key: ACCESS_KEY + secretAccessKey: + name: {{ .Values.database.backups.secretName }} + key: SECRET_KEY + {{ end }} diff --git a/charts/immich/templates/database/pod-monitor.yaml b/charts/immich/templates/database/pod-monitor.yaml new file mode 100644 index 0000000..3dd0d9a --- /dev/null +++ b/charts/immich/templates/database/pod-monitor.yaml @@ -0,0 +1,17 @@ +{{- if .Values.database.monitoring.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: {{ template "common.fullname" . }}-data + labels: + app.kubernetes.io/name: {{ template "common.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "immich" + {{- include "common.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + "cnpg.io/cluster": {{ .Values.database.clusterName }} + podMetricsEndpoints: + - port: metrics + {{- end }} diff --git a/charts/immich/templates/ingress.yaml b/charts/immich/templates/ingress.yaml new file mode 100644 index 0000000..f81fe41 --- /dev/null +++ b/charts/immich/templates/ingress.yaml @@ -0,0 +1,33 @@ +{{ if .Values.ingress.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ template "common.fullname" . }} + annotations: {{ toYaml .Values.ingress.annotations | nindent 4 }} + labels: + app.kubernetes.io/name: {{ template "common.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "immich" + {{- include "common.labels" . | nindent 4 }} +spec: + {{- if .Values.ingress.class}} + ingressClassName: {{ .Values.ingress.class }} + {{- end }} + rules: + - host: {{ .Values.ingress.domain }} + http: + paths: + - backend: + service: + name: {{ template "common.fullname" . }} + port: + number: 3001 + path: / + pathType: Prefix + {{- if .Values.ingress.tls.enabled }} + tls: + - hosts: + - {{ .Values.ingress.domain }} + secretName: {{ .Values.ingress.tls.secretName}} + {{- end }} +{{ end }} diff --git a/charts/immich/templates/machine-learning/deployment.yaml b/charts/immich/templates/machine-learning/deployment.yaml new file mode 100644 index 0000000..93a5ac2 --- /dev/null +++ b/charts/immich/templates/machine-learning/deployment.yaml @@ -0,0 +1,63 @@ +kind: Deployment +apiVersion: apps/v1 +metadata: + name: {{ template "common.fullname" . }}-machine-learning + labels: + app.kubernetes.io/name: {{ template "common.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "immich-machine-learning" + {{- include "common.labels" . | nindent 4 }} +spec: + revisionHistoryLimit: 0 + replicas: {{ .Values.server.replicas }} + strategy: + type: Recreate + selector: + matchLabels: + app.kubernetes.io/name: {{ template "common.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "immich-machine-learning" + template: + metadata: + labels: + app.kubernetes.io/name: {{ template "common.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "immich-machine-learning" + {{- include "common.labels" . | nindent 8 }} + spec: + containers: + - name: server + image: "{{ .Values.machineLearning.image.registry }}/{{ .Values.machineLearning.image.repository }}:{{ .Values.machineLearning.image.tag }}" + imagePullPolicy: {{ .Values.machineLearning.image.pullPolicy }} + env: + - name: IMMICH_PORT + value: "3003" + - name: TRANSFORMERS_CACHE + value: /cache + livenessProbe: + initialDelaySeconds: 0 + timeoutSeconds: 1 + periodSeconds: 10 + failureThreshold: 3 + httpGet: + port: http + path: /ping + readinessProbe: + initialDelaySeconds: 0 + timeoutSeconds: 1 + periodSeconds: 10 + failureThreshold: 3 + httpGet: + port: http + path: /ping + volumeMounts: + - name: cache + mountPath: /cache + ports: + - name: http + containerPort: 3003 + protocol: TCP + resources: {{ toYaml .Values.machineLearning.resources | nindent 12 }} + volumes: + - name: cache + emptyDir: {} diff --git a/charts/immich/templates/machine-learning/service.yaml b/charts/immich/templates/machine-learning/service.yaml new file mode 100644 index 0000000..e3778c5 --- /dev/null +++ b/charts/immich/templates/machine-learning/service.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "common.fullname" . }}-machine-learning + labels: + app.kubernetes.io/name: {{ template "common.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "immich-machine-learning" + {{- include "common.labels" . | nindent 4 }} +spec: + type: ClusterIP + ports: + - port: 3003 + targetPort: 3003 + protocol: TCP + name: http + selector: + app.kubernetes.io/name: {{ template "common.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "immich-machine-learning" diff --git a/charts/immich/templates/pvc-library.yaml b/charts/immich/templates/pvc-library.yaml new file mode 100644 index 0000000..02ec0ed --- /dev/null +++ b/charts/immich/templates/pvc-library.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ template "common.fullname" . }}-library + labels: + app.kubernetes.io/name: {{ template "common.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "immich" + {{- include "common.labels" . | nindent 4 }} +spec: + accessModes: + - {{ .Values.persistence.accessMode }} + resources: + requests: + storage: {{ .Values.persistence.size }} + {{- with .Values.persistence.storageClass }} + storageClassName: {{ . }} + {{- end }} diff --git a/charts/immich/templates/server/deployment.yaml b/charts/immich/templates/server/deployment.yaml new file mode 100644 index 0000000..a1b5706 --- /dev/null +++ b/charts/immich/templates/server/deployment.yaml @@ -0,0 +1,93 @@ +kind: Deployment +apiVersion: apps/v1 +metadata: + name: {{ template "common.fullname" . }}-server + labels: + app.kubernetes.io/name: {{ template "common.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "immich-server" + {{- include "common.labels" . | nindent 4 }} +spec: + revisionHistoryLimit: 0 + replicas: {{ .Values.server.replicas }} + strategy: + type: Recreate + selector: + matchLabels: + app.kubernetes.io/name: {{ template "common.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "immich-server" + template: + metadata: + labels: + app.kubernetes.io/name: {{ template "common.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "immich-server" + {{- include "common.labels" . | nindent 8 }} + spec: + containers: + - name: server + image: "{{ .Values.server.image.registry }}/{{ .Values.server.image.repository }}:{{ .Values.server.image.tag }}" + imagePullPolicy: {{ .Values.server.image.pullPolicy }} + env: + - name: IMMICH_METRICS + value: "true" + - name: IMMICH_METRICS_PORT + value: "8081" + - name: IMMICH_PORT + value: "3001" + - name: DB_HOSTNAME + valueFrom: + secretKeyRef: + name: {{ .Values.database.clusterName }}-app + key: host + - name: DB_USERNAME + valueFrom: + secretKeyRef: + name: {{ .Values.database.clusterName }}-app + key: username + - name: DB_DATABASE_NAME + valueFrom: + secretKeyRef: + name: {{ .Values.database.clusterName }}-app + key: dbname + - name: REDIS_HOSTNAME + value: {{ .Release.Name }}-redis-master + - name: IMMICH_MACHINE_LEARNING_URL + value: http://{{ template "common.fullname" . }}-machine-learning:3003 + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.database.clusterName }}-app + key: password + livenessProbe: + initialDelaySeconds: 0 + timeoutSeconds: 1 + periodSeconds: 10 + failureThreshold: 3 + httpGet: + port: http + path: /api/server-info/ping + readinessProbe: + initialDelaySeconds: 0 + timeoutSeconds: 1 + periodSeconds: 10 + failureThreshold: 3 + httpGet: + port: http + path: /api/server-info/ping + volumeMounts: + - name: library + mountPath: /usr/src/app/upload + ports: + - name: http + containerPort: 3001 + protocol: TCP + - name: metrics + containerPort: 8081 + protocol: TCP + resources: {{ toYaml .Values.server.resources | nindent 12 }} + volumes: + - name: library + persistentVolumeClaim: + claimName: {{ template "common.fullname" . }}-library diff --git a/charts/immich/templates/server/service-metrics.yaml b/charts/immich/templates/server/service-metrics.yaml new file mode 100644 index 0000000..df85379 --- /dev/null +++ b/charts/immich/templates/server/service-metrics.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "common.fullname" . }}-server-metrics + labels: + app.kubernetes.io/name: {{ template "common.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "immich-server" + {{- include "common.labels" . | nindent 4 }} +spec: + type: ClusterIP + ports: + - port: 8081 + targetPort: 8081 + protocol: TCP + name: metrics + selector: + app.kubernetes.io/name: {{ template "common.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "immich-server" diff --git a/charts/immich/templates/server/service-monitor.yaml b/charts/immich/templates/server/service-monitor.yaml new file mode 100644 index 0000000..8cd86e8 --- /dev/null +++ b/charts/immich/templates/server/service-monitor.yaml @@ -0,0 +1,18 @@ +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "common.fullname" . }}-server + labels: + app.kubernetes.io/name: {{ template "common.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "immich-server" + {{- include "common.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + app.kubernetes.io/name: {{ template "common.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "immich-server" + endpoints: + - port: metrics + scheme: http diff --git a/charts/immich/templates/server/service.yaml b/charts/immich/templates/server/service.yaml new file mode 100644 index 0000000..50cbc82 --- /dev/null +++ b/charts/immich/templates/server/service.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "common.fullname" . }} + labels: + app.kubernetes.io/name: {{ template "common.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "immich" + {{- include "common.labels" . | nindent 4 }} +spec: + type: ClusterIP + ports: + - port: 3001 + targetPort: 3001 + protocol: TCP + name: http + selector: + app.kubernetes.io/name: {{ template "common.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "immich-server" diff --git a/charts/immich/values.yaml b/charts/immich/values.yaml new file mode 100644 index 0000000..c9399bf --- /dev/null +++ b/charts/immich/values.yaml @@ -0,0 +1,71 @@ +persistence: + size: 200Gi + storageClass: '' + accessMode: ReadWriteMany + +ingress: + enabled: true + domain: immich.example.com + annotations: + # proxy-body-size is set to 0 to remove the body limit on file uploads +# nginx.ingress.kubernetes.io/proxy-body-size: "0" + tls: + enabled: true + secretName: immich-tls + +database: + image: + registry: ghcr.io + repository: tensorchord/cloudnative-pgvecto.rs + tag: 16.3 + + clusterName: immich-postgresql + logLevel: error + replicas: 2 + monitoring: + enabled: true + size: 32Gi + backups: + enabled: false + secretName: '' + retention: '' + path: '' + endpoint: '' + +machineLearning: + replicas: 1 + image: + registry: ghcr.io + repository: immich-app/immich-machine-learning + tag: v1.106.4 + pullPolicy: IfNotPresent + +# resources: +# requests: +# cpu: 10m +# memory: 128Mi +# limits: +# memory: 512Mi + +server: + replicas: 1 + image: + registry: ghcr.io + repository: immich-app/immich-server + tag: v1.106.4 + pullPolicy: IfNotPresent + +# resources: +# requests: +# cpu: 10m +# memory: 128Mi +# limits: +# memory: 512Mi + +redis: + enabled: true + architecture: standalone + auth: + enabled: false + master: + revisionHistoryLimit: 0 diff --git a/charts/infro/Chart.yaml b/charts/infro/Chart.yaml index f8509d9..3f30264 100644 --- a/charts/infro/Chart.yaml +++ b/charts/infro/Chart.yaml @@ -1,3 +1,3 @@ apiVersion: v2 name: infro -version: 1.0.5 +version: 1.0.6 diff --git a/charts/infro/templates/_helpers.tpl b/charts/infro/templates/_helpers.tpl index 467a9d9..6c1d0e5 100644 --- a/charts/infro/templates/_helpers.tpl +++ b/charts/infro/templates/_helpers.tpl @@ -14,7 +14,7 @@ {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} {{- end -}} -{{- define "labels" -}} +{{- define "common.labels" -}} app.kubernetes.io/version: {{ .Chart.Version | quote }} app.kubernetes.io/managed-by: {{ .Release.Service }} helm.sh/chart: {{ include "chartName" . }} diff --git a/charts/infro/templates/deployment.yaml b/charts/infro/templates/deployment.yaml index d9d5b7f..c148379 100644 --- a/charts/infro/templates/deployment.yaml +++ b/charts/infro/templates/deployment.yaml @@ -6,7 +6,7 @@ metadata: app.kubernetes.io/name: {{ template "common.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/component: "core" - {{- include "labels" . | nindent 4 }} + {{- include "common.labels" . | nindent 4 }} spec: revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} replicas: {{ .Values.replicas }} @@ -22,7 +22,7 @@ spec: app.kubernetes.io/name: {{ template "common.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/component: "core" - {{- include "labels" . | nindent 8 }} + {{- include "common.labels" . | nindent 8 }} spec: nodeSelector: {{ .Values.nodeSelector | toYaml | nindent 8 }} securityContext: {{ toYaml .Values.podSecurityContext | nindent 8 }} diff --git a/charts/infro/templates/secret.yaml b/charts/infro/templates/secret.yaml index 7402ec6..14ef1db 100644 --- a/charts/infro/templates/secret.yaml +++ b/charts/infro/templates/secret.yaml @@ -7,7 +7,7 @@ metadata: app.kubernetes.io/name: {{ template "common.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/component: "core" - {{- include "labels" . | nindent 4 }} + {{- include "common.labels" . | nindent 4 }} stringData: owner: {{ .Values.config.owner | quote }} config: {{ .Values.config.config | quote }}