# kubectl -n paperless create secret generic paperless-proxy --from-literal=cookie_secret=$(pwgen 32 1) --from-literal=oidc_secret=... # kubectl -n paperless create secret generic paperless --from-literal=postgres_password=$(pwgen 32 1) --from-literal=redis_password=$(pwgen 32 1) --from-literal=secret_key=$(pwgen 32 1) # There is no way of handling superusers (Admin panel access) automatically when # using OAuth2-Proxy, thus we need to run the following command to mark the # first user as such: # kubectl -n paperless exec -it deploy/paperless -c paperless -- python ./manage.py shell -c "from django.contrib.auth.models import User; u = User.objects.get_by_natural_key('informatic'); u.is_superuser = True; u.is_staff = True; u.save()" local kube = import "../../kube/hscloud.libsonnet"; local postgres = import "../../kube/postgres.libsonnet"; local redis = import "../../kube/redis.libsonnet"; { local app = self, local cfg = self.cfg, cfg:: { namespace: "paperless", domain: "paperless.hackerspace.pl", images: { paperless: "registry.k0.hswaw.net/informatic/paperless-ngx:1.17.4", proxy: "quay.io/oauth2-proxy/oauth2-proxy:v7.2.1", }, storageClassName: "waw-hdd-redundant-3", }, ns: kube.Namespace(cfg.namespace), redis: redis { cfg+: { namespace: cfg.namespace, storageClassName: cfg.storageClassName, appName: "paperless", image: "redis:6.0", password: { secretKeyRef: { name: "paperless", key: "redis_password" } }, }, }, postgres: postgres { cfg+: { namespace: cfg.namespace, appName: "paperless", database: "paperless", username: "paperless", password: { secretKeyRef: { name: "paperless", key: "postgres_password" } }, storageClassName: cfg.storageClassName, storageSize: "20Gi", image: "postgres:15.4-bookworm", pgupgrade+: { enable: true, from: "10", }, }, bouncer: {}, }, dataVolume: app.ns.Contain(kube.PersistentVolumeClaim("paperless-data")) { spec+: { storageClassName: cfg.storageClassName, accessModes: [ "ReadWriteOnce" ], resources: { requests: { storage: "100Gi", }, }, }, }, deploy: app.ns.Contain(kube.Deployment("paperless")) { spec+: { replicas: 1, template+: { spec+: { volumes_: { data: kube.PersistentVolumeClaimVolume(app.dataVolume), }, securityContext: { runAsUser: 1000, runAsGroup: 1000, fsGroup: 1000, }, default_container:: "auth", containers_: { auth: kube.Container("authproxy") { image: cfg.images.proxy, ports_: { http: { containerPort: 8001 }, }, env_: { OAUTH2_PROXY_UPSTREAMS: "http://127.0.0.1:8000", OAUTH2_PROXY_HTTP_ADDRESS: "0.0.0.0:8001", OAUTH2_PROXY_COOKIE_SECRET: { secretKeyRef: { name: "paperless-proxy", key: "cookie_secret" } }, OAUTH2_PROXY_PROVIDER: "oidc", OAUTH2_PROXY_OIDC_ISSUER_URL: "https://sso.hackerspace.pl", OAUTH2_PROXY_SKIP_PROVIDER_BUTTON: "true", OAUTH2_PROXY_CLIENT_ID: "b4859334-140b-432a-81f6-8f3e135e021a", OAUTH2_PROXY_CLIENT_SECRET: { secretKeyRef: { name: "paperless-proxy", key: "oidc_secret" } }, OAUTH2_PROXY_EMAIL_DOMAINS: "*", OAUTH2_PROXY_ALLOWED_GROUPS: "zarzad,paperless-admin", # Security considerations: # # * OAuth2-Proxy *will* strip X-Forwarded-User # header from requests passed through to # endpoint, preventing authentication bypass # # * OAuth2-Proxy *will not* strip Authorization # header - that can either be a user token, # or a username/password pair. Former can only # be generated by staff/superuser in Admin # panel, and the latter will not work for our # OAuth2 autogenerated users since these do # not have any password set OAUTH2_PROXY_SKIP_AUTH_ROUTES: "^/api/.*", }, }, paperless: kube.Container("paperless") { image: cfg.images.paperless, resources: { requests: { cpu: "500m", memory: "1024M" }, limits: { cpu: "4", memory: "6144M" }, }, env_: { PAPERLESS_PORT: "8000", PAPERLESS_URL: "https://%s" % [cfg.domain], PAPERLESS_SECRET_KEY: { secretKeyRef: { name: "paperless", key: "secret_key" } }, A_REDIS_PASSWORD: app.redis.cfg.password, PAPERLESS_REDIS: "redis://:$(A_REDIS_PASSWORD)@redis:6379", PAPERLESS_DBHOST: "postgres", PAPERLESS_DBNAME: app.postgres.cfg.database, PAPERLESS_DBUSER: app.postgres.cfg.username, PAPERLESS_DBPASS: app.postgres.cfg.password, PAPERLESS_ENABLE_HTTP_REMOTE_USER: "true", PAPERLESS_HTTP_REMOTE_USER_HEADER_NAME: "HTTP_X_FORWARDED_USER", PAPERLESS_OCR_LANGUAGE: "pol", PAPERLESS_OCR_MODE: "force", PAPERLESS_DATE_ORDER: "YMD", PAPERLESS_EMAIL_TASK_CRON: "*/2 * * * *", }, volumeMounts: [ { name: "data", mountPath: "/usr/src/paperless/data", subPath: "data" }, { name: "data", mountPath: "/usr/src/paperless/media", subPath: "media" }, { name: "data", mountPath: "/usr/src/paperless/consume", subPath: "consume" }, ], }, }, }, }, }, }, service: app.ns.Contain(kube.Service("paperless")) { target_pod:: app.deploy.spec.template, }, ingress: app.ns.Contain(kube.SimpleIngress("paperless")) { hosts:: [cfg.domain], target_service:: app.service, }, }