From 3e13c355f557bd9392ecab3339aae0aeb3c71f56 Mon Sep 17 00:00:00 2001 From: Morten Olsen Date: Thu, 8 Jan 2026 12:06:10 +0100 Subject: [PATCH] add paperless-ngx --- apps/charts/paperless-ngx/Chart.yaml | 7 + .../paperless-ngx/templates/client.yaml | 1 + .../paperless-ngx/templates/database.yaml | 1 + .../paperless-ngx/templates/deployment.yaml | 105 +++++++++++++ .../templates/oidc-providers-secret.yaml | 11 ++ apps/charts/paperless-ngx/templates/pvc.yaml | 1 + apps/charts/paperless-ngx/templates/role.yaml | 15 ++ .../paperless-ngx/templates/rolebinding.yaml | 16 ++ .../templates/secret-external-secrets.yaml | 1 + .../templates/secret-password-generators.yaml | 1 + .../paperless-ngx/templates/service.yaml | 1 + .../templates/serviceaccount.yaml | 8 + .../templates/virtual-service.yaml | 1 + apps/charts/paperless-ngx/values.yaml | 148 ++++++++++++++++++ 14 files changed, 317 insertions(+) create mode 100644 apps/charts/paperless-ngx/Chart.yaml create mode 100644 apps/charts/paperless-ngx/templates/client.yaml create mode 100644 apps/charts/paperless-ngx/templates/database.yaml create mode 100644 apps/charts/paperless-ngx/templates/deployment.yaml create mode 100644 apps/charts/paperless-ngx/templates/oidc-providers-secret.yaml create mode 100644 apps/charts/paperless-ngx/templates/pvc.yaml create mode 100644 apps/charts/paperless-ngx/templates/role.yaml create mode 100644 apps/charts/paperless-ngx/templates/rolebinding.yaml create mode 100644 apps/charts/paperless-ngx/templates/secret-external-secrets.yaml create mode 100644 apps/charts/paperless-ngx/templates/secret-password-generators.yaml create mode 100644 apps/charts/paperless-ngx/templates/service.yaml create mode 100644 apps/charts/paperless-ngx/templates/serviceaccount.yaml create mode 100644 apps/charts/paperless-ngx/templates/virtual-service.yaml create mode 100644 apps/charts/paperless-ngx/values.yaml diff --git a/apps/charts/paperless-ngx/Chart.yaml b/apps/charts/paperless-ngx/Chart.yaml new file mode 100644 index 0000000..ebcf91a --- /dev/null +++ b/apps/charts/paperless-ngx/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +version: 1.0.0 +name: paperless-ngx +dependencies: + - name: common + version: 1.0.0 + repository: file://../../common diff --git a/apps/charts/paperless-ngx/templates/client.yaml b/apps/charts/paperless-ngx/templates/client.yaml new file mode 100644 index 0000000..c13745f --- /dev/null +++ b/apps/charts/paperless-ngx/templates/client.yaml @@ -0,0 +1 @@ +{{ include "common.oidc" . }} diff --git a/apps/charts/paperless-ngx/templates/database.yaml b/apps/charts/paperless-ngx/templates/database.yaml new file mode 100644 index 0000000..8a7fad4 --- /dev/null +++ b/apps/charts/paperless-ngx/templates/database.yaml @@ -0,0 +1 @@ +{{ include "common.database" . }} diff --git a/apps/charts/paperless-ngx/templates/deployment.yaml b/apps/charts/paperless-ngx/templates/deployment.yaml new file mode 100644 index 0000000..9de6145 --- /dev/null +++ b/apps/charts/paperless-ngx/templates/deployment.yaml @@ -0,0 +1,105 @@ +{{- if .Values.deployment }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "common.fullname" . }} + labels: + {{- include "common.labels" . | nindent 4 }} +spec: + strategy: + type: {{ include "common.deploymentStrategy" . }} + {{- if hasKey .Values.deployment "replicas" }} + replicas: {{ .Values.deployment.replicas }} + {{- else }} + replicas: {{ .Values.deployment.replicas }} + {{- end }} + {{- if hasKey .Values.deployment "revisionHistoryLimit" }} + revisionHistoryLimit: {{ .Values.deployment.revisionHistoryLimit }} + {{- else }} + revisionHistoryLimit: 2 + {{- end }} + selector: + matchLabels: + {{- include "common.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- if .Values.deployment.podAnnotations }} + annotations: + {{- toYaml .Values.deployment.podAnnotations | nindent 8 }} + {{- end }} + labels: + {{- include "common.selectorLabels" . | nindent 8 }} + spec: + {{- if .Values.oidc.enabled }} + serviceAccountName: {{ include "common.fullname" . }}-oidc-config + {{- else if .Values.deployment.serviceAccountName }} + serviceAccountName: {{ .Values.deployment.serviceAccountName | replace "{release}" .Release.Name | replace "{fullname}" (include "common.fullname" .) }} + {{- end }} + {{- if .Values.deployment.hostNetwork }} + hostNetwork: {{ .Values.deployment.hostNetwork }} + {{- end }} + {{- include "common.dnsConfig" . | nindent 6 }} + {{- if .Values.oidc.enabled }} + initContainers: + - name: oidc-config-generator + image: bitnami/kubectl:latest + command: + - sh + - -c + - | + CLIENT_ID=$(kubectl get secret {{ .Release.Name }}-oidc-credentials -o jsonpath='{.data.clientId}' | base64 -d) + CLIENT_SECRET=$(kubectl get secret {{ .Release.Name }}-oidc-credentials -o jsonpath='{.data.clientSecret}' | base64 -d) + ISSUER=$(kubectl get secret {{ .Release.Name }}-oidc-credentials -o jsonpath='{.data.issuer}' | base64 -d) + # Construct well-known URL from issuer + SERVER_URL="${ISSUER}/.well-known/openid-configuration" + JSON="{\"openid_connect\":{\"OAUTH_PKCE_ENABLED\":true,\"APPS\":[{\"provider_id\":\"authentik\",\"name\":\"authentik\",\"client_id\":\"$CLIENT_ID\",\"secret\":\"$CLIENT_SECRET\",\"settings\":{\"server_url\":\"$SERVER_URL\"}}]}" + kubectl create secret generic {{ include "common.fullname" . }}-oidc-providers --from-literal=providers="$JSON" --dry-run=client -o yaml | kubectl apply -f - + env: + - name: KUBERNETES_SERVICE_HOST + value: "kubernetes.default.svc" + - name: KUBERNETES_SERVICE_PORT + value: "443" + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy | default "IfNotPresent" }} + {{- if .Values.command }} + command: {{- toYaml .Values.command | nindent 12 }} + {{- end }} + {{- if .Values.args }} + args: {{- toYaml .Values.args | nindent 12 }} + {{- end }} + ports: +{{ include "common.containerPorts" . | indent 12 }} + {{- if .Values.container.healthProbe }} + livenessProbe: +{{ include "common.healthProbe" . | indent 12 }} + readinessProbe: +{{ include "common.healthProbe" . | indent 12 }} + {{- end }} + {{- if .Values.container.securityContext }} + securityContext: + {{- toYaml .Values.container.securityContext | nindent 12 }} + {{- end }} + {{- if .Values.volumes }} + volumeMounts: +{{ include "common.volumeMounts" . | indent 12 }} + {{- end }} + {{- if or .Values.env .Values.globals.timezone .Values.oidc.enabled }} + env: +{{ include "common.env" . | indent 12 }} +{{- if .Values.oidc.enabled }} + - name: PAPERLESS_SOCIALACCOUNT_PROVIDERS + valueFrom: + secretKeyRef: + name: {{ include "common.fullname" . }}-oidc-providers + key: providers +{{- end }} + {{- end }} + {{- if .Values.volumes }} + volumes: + {{- include "common.volumes" . | nindent 8 }} + {{- end }} +{{- end }} + diff --git a/apps/charts/paperless-ngx/templates/oidc-providers-secret.yaml b/apps/charts/paperless-ngx/templates/oidc-providers-secret.yaml new file mode 100644 index 0000000..efd6664 --- /dev/null +++ b/apps/charts/paperless-ngx/templates/oidc-providers-secret.yaml @@ -0,0 +1,11 @@ +{{- if .Values.oidc.enabled }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "common.fullname" . }}-oidc-providers + labels: + {{- include "common.labels" . | nindent 4 }} +type: Opaque +stringData: + providers: "" +{{- end }} diff --git a/apps/charts/paperless-ngx/templates/pvc.yaml b/apps/charts/paperless-ngx/templates/pvc.yaml new file mode 100644 index 0000000..379bad9 --- /dev/null +++ b/apps/charts/paperless-ngx/templates/pvc.yaml @@ -0,0 +1 @@ +{{ include "common.pvc" . }} diff --git a/apps/charts/paperless-ngx/templates/role.yaml b/apps/charts/paperless-ngx/templates/role.yaml new file mode 100644 index 0000000..a668e09 --- /dev/null +++ b/apps/charts/paperless-ngx/templates/role.yaml @@ -0,0 +1,15 @@ +{{- if .Values.oidc.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "common.fullname" . }}-oidc-config + labels: + {{- include "common.labels" . | nindent 4 }} +rules: +- apiGroups: [""] + resources: ["secrets"] + resourceNames: + - {{ .Release.Name }}-oidc-credentials + - {{ include "common.fullname" . }}-oidc-providers + verbs: ["get", "create", "update", "patch"] +{{- end }} diff --git a/apps/charts/paperless-ngx/templates/rolebinding.yaml b/apps/charts/paperless-ngx/templates/rolebinding.yaml new file mode 100644 index 0000000..ec2c00d --- /dev/null +++ b/apps/charts/paperless-ngx/templates/rolebinding.yaml @@ -0,0 +1,16 @@ +{{- if .Values.oidc.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "common.fullname" . }}-oidc-config + labels: + {{- include "common.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "common.fullname" . }}-oidc-config +subjects: +- kind: ServiceAccount + name: {{ include "common.fullname" . }}-oidc-config + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/apps/charts/paperless-ngx/templates/secret-external-secrets.yaml b/apps/charts/paperless-ngx/templates/secret-external-secrets.yaml new file mode 100644 index 0000000..de340c4 --- /dev/null +++ b/apps/charts/paperless-ngx/templates/secret-external-secrets.yaml @@ -0,0 +1 @@ +{{ include "common.externalSecrets.externalSecrets" . }} diff --git a/apps/charts/paperless-ngx/templates/secret-password-generators.yaml b/apps/charts/paperless-ngx/templates/secret-password-generators.yaml new file mode 100644 index 0000000..2183e0a --- /dev/null +++ b/apps/charts/paperless-ngx/templates/secret-password-generators.yaml @@ -0,0 +1 @@ +{{ include "common.externalSecrets.passwordGenerators" . }} diff --git a/apps/charts/paperless-ngx/templates/service.yaml b/apps/charts/paperless-ngx/templates/service.yaml new file mode 100644 index 0000000..f024c64 --- /dev/null +++ b/apps/charts/paperless-ngx/templates/service.yaml @@ -0,0 +1 @@ +{{ include "common.service" . }} diff --git a/apps/charts/paperless-ngx/templates/serviceaccount.yaml b/apps/charts/paperless-ngx/templates/serviceaccount.yaml new file mode 100644 index 0000000..c97c3be --- /dev/null +++ b/apps/charts/paperless-ngx/templates/serviceaccount.yaml @@ -0,0 +1,8 @@ +{{- if .Values.oidc.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "common.fullname" . }}-oidc-config + labels: + {{- include "common.labels" . | nindent 4 }} +{{- end }} diff --git a/apps/charts/paperless-ngx/templates/virtual-service.yaml b/apps/charts/paperless-ngx/templates/virtual-service.yaml new file mode 100644 index 0000000..766f6b9 --- /dev/null +++ b/apps/charts/paperless-ngx/templates/virtual-service.yaml @@ -0,0 +1 @@ +{{ include "common.virtualService" . }} diff --git a/apps/charts/paperless-ngx/values.yaml b/apps/charts/paperless-ngx/values.yaml new file mode 100644 index 0000000..5945ce1 --- /dev/null +++ b/apps/charts/paperless-ngx/values.yaml @@ -0,0 +1,148 @@ +image: + repository: ghcr.io/paperless-ngx/paperless-ngx + tag: latest + pullPolicy: IfNotPresent + +subdomain: paperless + +# Deployment configuration +deployment: + strategy: Recreate + replicas: 1 + revisionHistoryLimit: 0 + +# Container configuration +container: + port: 8000 + healthProbe: + type: httpGet + path: /api/ + port: http + +# Service configuration +service: + port: 80 + type: ClusterIP + +# Volume configuration +volumes: + - name: data + mountPath: /usr/src/paperless/data + persistentVolumeClaim: data + - name: media + mountPath: /usr/src/paperless/media + persistentVolumeClaim: media + - name: consume + mountPath: /usr/src/paperless/consume + persistentVolumeClaim: consume + - name: export + mountPath: /usr/src/paperless/export + persistentVolumeClaim: export + +# Persistent volume claims +persistentVolumeClaims: + - name: data + size: 10Gi + storageClassName: persistent + - name: media + size: 50Gi + storageClassName: persistent + - name: consume + size: 5Gi + storageClassName: persistent + - name: export + size: 5Gi + storageClassName: persistent + +# VirtualService configuration +virtualService: + enabled: true + gateways: + public: true + private: true + +# OIDC client configuration +oidc: + enabled: true + redirectUris: + - "/accounts/oidc/authentik/login/callback/" + subjectMode: user_username + +# Database configuration +database: + enabled: true + +# External Secrets configuration +externalSecrets: + - name: "{release}-secrets" + passwords: + - name: secretkey + length: 64 + encoding: hex + allowRepeat: false + secretKeys: + - secretkey + +# Environment variables +env: + TZ: + value: "{timezone}" + PAPERLESS_URL: + value: "https://{subdomain}.{domain}" + PAPERLESS_SECRET_KEY: + valueFrom: + secretKeyRef: + name: "{release}-secrets" + key: secretkey + # Database configuration + PAPERLESS_DBENGINE: postgresql + PAPERLESS_DBHOST: + valueFrom: + secretKeyRef: + name: "{release}-connection" + key: host + PAPERLESS_DBPORT: + valueFrom: + secretKeyRef: + name: "{release}-connection" + key: port + PAPERLESS_DBNAME: + valueFrom: + secretKeyRef: + name: "{release}-connection" + key: database + PAPERLESS_DBUSER: + valueFrom: + secretKeyRef: + name: "{release}-connection" + key: user + PAPERLESS_DBPASS: + valueFrom: + secretKeyRef: + name: "{release}-connection" + key: password + # Redis configuration (external Redis required) + # Update these values to point to your Redis instance + PAPERLESS_REDIS: redis://redis.shared.svc.cluster.local:6379 + # OIDC configuration using django-allauth + PAPERLESS_ENABLE_ALLAUTH: "true" + PAPERLESS_APPS: "allauth.socialaccount.providers.openid_connect" + # PAPERLESS_SOCIALACCOUNT_PROVIDERS is set via init container (see deployment.yaml) + PAPERLESS_SOCIALACCOUNT_ALLOW_SIGNUPS: "true" + PAPERLESS_SOCIAL_AUTO_SIGNUP: "true" + # OIDC credentials for init container (will be used to construct JSON) + PAPERLESS_OIDC_CLIENT_ID: + valueFrom: + secretKeyRef: + name: "{release}-oidc-credentials" + key: clientId + PAPERLESS_OIDC_CLIENT_SECRET: + valueFrom: + secretKeyRef: + name: "{release}-oidc-credentials" + key: clientSecret + PAPERLESS_OIDC_ISSUER_URL: + valueFrom: + secretKeyRef: + name: "{release}-oidc-credentials" + key: issuer