{ globals, lib, config, ... }: { options.paperless.enable = lib.mkEnableOption "paperless"; config = lib.mkIf config.paperless.enable { kubernetes.resources = { secrets = { database.stringData.password = "ref+sops://secrets.yml#/paperless/databasePassword"; server.stringData.secretKey = "ref+sops://secrets.yml#/paperless/secretKey"; }; deployments = { server.spec = { selector.matchLabels = { app = "paperless"; component = "web"; }; strategy = { type = "RollingUpdate"; rollingUpdate = { maxSurge = 0; maxUnavailable = 1; }; }; template = { metadata.labels = { app = "paperless"; component = "web"; }; spec = { volumes.data.persistentVolumeClaim.claimName = "data"; containers.paperless = { image = globals.images.paperless; imagePullPolicy = "IfNotPresent"; ports.web.containerPort = 8000; env = { PAPERLESS_REDIS.value = "redis://redis.paperless.svc.cluster.local:6379"; PAPERLESS_DBENGINE.value = "postgresql"; PAPERLESS_DBHOST.value = "database.paperless.svc.cluster.local"; PAPERLESS_DBNAME.value = "paperless"; PAPERLESS_DBUSER.value = "paperless"; PAPERLESS_DATA_DIR.value = "/data/"; PAPERLESS_MEDIA_ROOT.value = "/data/"; PAPERLESS_OCR_LANGUAGES.value = "nld eng"; PAPERLESS_URL.value = "https://paperless.griffin-mermaid.ts.net"; PAPERLESS_TIME_ZONE.value = "Europe/Amsterdam"; PAPERLESS_OCR_LANGUAGE.value = "nld"; USERMAP_UID.value = "33"; USERMAP_GID.value = "33"; PAPERLESS_DBPASS.valueFrom.secretKeyRef = { name = "database"; key = "password"; }; PAPERLESS_SECRET_KEY.valueFrom.secretKeyRef = { name = "server"; key = "secretKey"; }; }; volumeMounts = [ { name = "data"; mountPath = "/data"; } ]; }; securityContext = { fsGroup = 33; fsGroupChangePolicy = "OnRootMismatch"; }; }; }; }; redis.spec = { selector.matchLabels = { app = "paperless"; component = "redis"; }; strategy = { type = "RollingUpdate"; rollingUpdate = { maxSurge = 0; maxUnavailable = 1; }; }; template = { metadata.labels = { app = "paperless"; component = "redis"; }; spec = { volumes.data.persistentVolumeClaim.claimName = "redisdata"; containers.redis = { image = globals.images.redis7; ports.redis.containerPort = 6379; imagePullPolicy = "IfNotPresent"; volumeMounts = [ { name = "data"; mountPath = "/data"; } ]; }; securityContext = { fsGroup = 999; fsGroupChangePolicy = "OnRootMismatch"; }; }; }; }; database.spec = { selector.matchLabels = { app = "paperless"; component = "database"; }; strategy = { type = "RollingUpdate"; rollingUpdate = { maxSurge = 0; maxUnavailable = 1; }; }; template = { metadata.labels = { app = "paperless"; component = "database"; }; spec = { containers.postgres = { image = globals.images.postgres15; ports.postgres.containerPort = 5432; imagePullPolicy = "IfNotPresent"; env = { POSTGRES_DB.value = "paperless"; POSTGRES_USER.value = "paperless"; PGDATA.value = "/pgdata/data"; POSTGRES_PASSWORD.valueFrom.secretKeyRef = { name = "database"; key = "password"; }; }; volumeMounts = [ { name = "data"; mountPath = "/pgdata"; } ]; }; volumes.data.persistentVolumeClaim.claimName = "database"; }; }; }; }; services = { web.spec = { type = "LoadBalancer"; loadBalancerIP = globals.paperlessIPv4; selector = { app = "paperless"; component = "web"; }; ports.web = { port = 80; targetPort = "web"; }; }; redis.spec = { selector = { app = "paperless"; component = "redis"; }; ports.redis = { port = 6379; targetPort = "redis"; }; }; database.spec = { selector = { app = "paperless"; component = "database"; }; ports.postgres = { port = 5432; targetPort = "postgres"; }; }; }; }; lab = { tailscaleIngresses.tailscale = { host = "paperless"; service.name = "web"; }; longhorn.persistentVolumeClaim = { data = { volumeName = "paperless-data"; storage = "10Gi"; }; redisdata = { volumeName = "paperless-redisdata"; storage = "20Mi"; }; database = { volumeName = "paperless-db"; storage = "150Mi"; }; }; }; }; }