--- # Namespace apiVersion: v1 kind: Namespace metadata: name: paperless-system --- # Service Account apiVersion: v1 kind: ServiceAccount metadata: name: default namespace: paperless-system --- # PVC for Redis data apiVersion: v1 kind: PersistentVolumeClaim metadata: name: paperless-redis namespace: paperless-system labels: app.kubernetes.io/instance: paperless app.kubernetes.io/name: redis spec: accessModes: - ReadWriteOnce storageClassName: longhorn resources: requests: storage: 1Gi --- # PVC for Paperless config/data (index, thumbnails, etc.) apiVersion: v1 kind: PersistentVolumeClaim metadata: name: paperless-config namespace: paperless-system labels: app.kubernetes.io/instance: paperless app.kubernetes.io/name: paperless spec: accessModes: - ReadWriteOnce storageClassName: longhorn resources: requests: storage: 10Gi --- # Redis Deployment apiVersion: apps/v1 kind: Deployment metadata: name: paperless-redis namespace: paperless-system labels: app.kubernetes.io/instance: paperless app.kubernetes.io/name: redis spec: replicas: 1 strategy: type: Recreate selector: matchLabels: app.kubernetes.io/instance: paperless app.kubernetes.io/name: redis template: metadata: labels: app.kubernetes.io/instance: paperless app.kubernetes.io/name: redis spec: containers: - name: redis image: redis:7-alpine imagePullPolicy: IfNotPresent ports: - name: redis containerPort: 6379 protocol: TCP resources: limits: cpu: "250m" memory: 256Mi requests: cpu: 50m memory: 64Mi livenessProbe: exec: command: - sh - -c - redis-cli ping | grep PONG initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 readinessProbe: exec: command: - sh - -c - redis-cli ping | grep PONG initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 5 volumeMounts: - name: data mountPath: /data volumes: - name: data persistentVolumeClaim: claimName: paperless-redis --- # Redis Service apiVersion: v1 kind: Service metadata: name: paperless-redis namespace: paperless-system labels: app.kubernetes.io/instance: paperless app.kubernetes.io/name: redis spec: type: ClusterIP ports: - name: redis port: 6379 targetPort: redis protocol: TCP selector: app.kubernetes.io/instance: paperless app.kubernetes.io/name: redis --- # Paperless-ngx Deployment apiVersion: apps/v1 kind: Deployment metadata: name: paperless namespace: paperless-system labels: app.kubernetes.io/instance: paperless app.kubernetes.io/name: paperless app.kubernetes.io/version: 2.20.6 spec: replicas: 1 strategy: type: Recreate selector: matchLabels: app.kubernetes.io/instance: paperless app.kubernetes.io/name: paperless template: metadata: labels: app.kubernetes.io/instance: paperless app.kubernetes.io/name: paperless app.kubernetes.io/version: 2.20.6 spec: enableServiceLinks: false containers: - name: paperless image: ghcr.io/paperless-ngx/paperless-ngx:2.20.15 imagePullPolicy: IfNotPresent env: # Database - using shared PostgreSQL in database-system namespace - name: PAPERLESS_DBENGINE value: postgresql - name: PAPERLESS_DBHOST value: postgresql-rw.database-system.svc.cluster.local - name: PAPERLESS_DBPORT value: "5432" - name: PAPERLESS_DBNAME value: paperless - name: PAPERLESS_DBUSER valueFrom: secretKeyRef: name: paperless-db key: username - name: PAPERLESS_DBPASS valueFrom: secretKeyRef: name: paperless-db key: password # Redis - name: PAPERLESS_REDIS value: redis://paperless-redis:6379 # Admin user - name: PAPERLESS_ADMIN_USER valueFrom: secretKeyRef: name: paperless-admin key: username - name: PAPERLESS_ADMIN_PASSWORD valueFrom: secretKeyRef: name: paperless-admin key: password - name: PAPERLESS_SECRET_KEY valueFrom: secretKeyRef: name: paperless-admin key: secret-key # OCR settings - name: PAPERLESS_OCR_LANGUAGE value: eng+hun - name: PAPERLESS_OCR_LANGUAGES value: eng hun # URLs - name: PAPERLESS_URL value: https://paperless.dooplex.hu # Paths - name: PAPERLESS_DATA_DIR value: /usr/src/paperless/data - name: PAPERLESS_MEDIA_ROOT value: /usr/src/paperless/media - name: PAPERLESS_CONSUMPTION_DIR value: /usr/src/paperless/consume - name: PAPERLESS_EXPORT_DIR value: /usr/src/paperless/export # Time zone - name: PAPERLESS_TIME_ZONE value: Europe/Budapest # SMTP Configuration - name: PAPERLESS_EMAIL_HOST valueFrom: secretKeyRef: name: smtp-credentials key: host - name: PAPERLESS_EMAIL_PORT valueFrom: secretKeyRef: name: smtp-credentials key: port - name: PAPERLESS_EMAIL_HOST_USER valueFrom: secretKeyRef: name: smtp-credentials key: username - name: PAPERLESS_EMAIL_HOST_PASSWORD valueFrom: secretKeyRef: name: smtp-credentials key: password - name: PAPERLESS_EMAIL_FROM valueFrom: secretKeyRef: name: smtp-credentials key: from-address - name: PAPERLESS_EMAIL_USE_TLS value: "true" - name: PAPERLESS_ENABLE_ALLAUTH value: "true" - name: PAPERLESS_APPS value: "allauth.socialaccount.providers.openid_connect" - name: PAPERLESS_SOCIALACCOUNT_PROVIDERS value: '{"openid_connect":{"APPS":[{"provider_id":"authentik","name":"authentik","client_id":"yJwhh4PnvxVCqyjSehj2pFLD31SeALmzMgyaR0Lg","secret":"Khf10AEnz8jsq4cMnqx1mhYFHk3pfbdatnpFr7HHbRWdnQpgHjJP5J60hJgMwTH21azNxaL3gXjeTd6AxMNVTFixWScukioO5e15GQAPUd8wQRdhM1OIz1NGXTsbW7Uw","settings":{"server_url":"https://authentik.dooplex.hu/application/o/paperless/.well-known/openid-configuration","claims":{"username":"email"}}}],"OAUTH_PKCE_ENABLED":"True"}}' - name: PAPERLESS_AUTO_LOGIN value: "true" - name: PAPERLESS_LOGOUT_REDIRECT_URL value: "https://authentik.dooplex.hu/application/o/paperless/end-session/" # Env values for checking worker health - name: PAPERLESS_TASK_WORKERS value: "2" - name: CELERY_WORKER_MAX_TASKS_PER_CHILD value: "100" # Restart worker after 100 tasks (prevents memory leaks/hangs) - name: CELERY_WORKER_MAX_MEMORY_PER_CHILD value: "1048576" # Restart if worker exceeds 1GB ports: - name: http containerPort: 8000 protocol: TCP resources: limits: cpu: "2" memory: 2Gi requests: cpu: 250m memory: 512Mi livenessProbe: httpGet: path: / port: http initialDelaySeconds: 60 periodSeconds: 30 timeoutSeconds: 10 failureThreshold: 5 readinessProbe: httpGet: path: / port: http initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 volumeMounts: - name: config mountPath: /usr/src/paperless/data - name: data mountPath: /usr/src/paperless/media - name: consume mountPath: /usr/src/paperless/consume - name: export mountPath: /usr/src/paperless/export volumes: - name: config persistentVolumeClaim: claimName: paperless-config - name: data hostPath: path: /mnt/4_hdd/data/paperless/media type: DirectoryOrCreate - name: consume hostPath: path: /mnt/4_hdd/data/paperless/consume type: DirectoryOrCreate - name: export hostPath: path: /mnt/4_hdd/data/paperless/export type: DirectoryOrCreate --- # Paperless Service apiVersion: v1 kind: Service metadata: name: paperless namespace: paperless-system labels: app.kubernetes.io/instance: paperless app.kubernetes.io/name: paperless app.kubernetes.io/version: 2.20.6 spec: type: ClusterIP ports: - name: http port: 8000 targetPort: http protocol: TCP selector: app.kubernetes.io/instance: paperless app.kubernetes.io/name: paperless --- # Ingress apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: paperless namespace: paperless-system annotations: cert-manager.io/cluster-issuer: letsencrypt-prod external-dns.alpha.kubernetes.io/hostname: paperless.dooplex.hu,paperless.home nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/proxy-body-size: "0" nginx.ingress.kubernetes.io/proxy-read-timeout: "600" nginx.ingress.kubernetes.io/proxy-send-timeout: "600" nginx.ingress.kubernetes.io/configuration-snippet: | set $geo_allowed 0; if ($remote_addr ~ "^192\.168\.") { set $geo_allowed 1; } if ($remote_addr ~ "^10\.") { set $geo_allowed 1; } if ($geoip2_country_code = "HU") { set $geo_allowed 1; } if ($geo_allowed = 0) { return 403 "Access restricted to Hungary"; } labels: app.kubernetes.io/instance: paperless app.kubernetes.io/name: paperless spec: ingressClassName: nginx-internal rules: - host: paperless.dooplex.hu http: paths: - path: / pathType: Prefix backend: service: name: paperless port: number: 8000 - host: paperless.home http: paths: - path: / pathType: Prefix backend: service: name: paperless port: number: 8000 tls: - hosts: - paperless.dooplex.hu secretName: paperless-tls