| # 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/kube.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@sha256:78b17e3050f7edea1e8c659c433ebcb6365bb93280a2698e3322075f988b1f41", |
| 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", |
| }, |
| 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", |
| |
| # 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_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", |
| }, |
| |
| 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.Ingress("paperless")) { |
| metadata+: { |
| annotations+: { |
| "kubernetes.io/tls-acme": "true", |
| "certmanager.k8s.io/cluster-issuer": "letsencrypt-prod", |
| "nginx.ingress.kubernetes.io/proxy-body-size": "0", |
| }, |
| }, |
| spec+: { |
| tls: [ { hosts: [ cfg.domain ], secretName: "paperless-tls" } ], |
| rules: [ |
| { |
| host: cfg.domain, |
| http: { |
| paths: [ |
| { path: "/", backend: app.service.name_port }, |
| ], |
| }, |
| }, |
| ], |
| }, |
| } |
| } |