| # 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 top = self, |
| local cfg = self.cfg, |
| |
| cfg:: { |
| name: "paperless", |
| 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", |
| }, |
| |
| secretRefs:: { |
| redis_password: { secretKeyRef: { name: "paperless", key: "redis_password" } }, |
| postgres_password: { secretKeyRef: { name: "paperless", key: "postgres_password" } }, |
| secret_key: { secretKeyRef: { name: "paperless", key: "secret_key" } }, |
| proxy: { |
| cookie_secret: { secretKeyRef: { name: "paperless-proxy", key: "cookie_secret" } }, |
| oidc_secret: { secretKeyRef: { name: "paperless-proxy", key: "oidc_secret" } }, |
| }, |
| }, |
| |
| local ns = kube.Namespace(cfg.namespace), |
| |
| redis: ns.Contain(redis) { |
| cfg+: { |
| storageClassName: cfg.storageClassName, |
| appName: "paperless", |
| image: "redis:6.0", |
| password: top.secretRefs.redis_password, |
| }, |
| }, |
| |
| postgres: ns.Contain(postgres) { |
| cfg+: { |
| appName: "paperless", |
| database: "paperless", |
| username: "paperless", |
| |
| password: top.secretRefs.postgres_password, |
| storageClassName: cfg.storageClassName, |
| storageSize: "20Gi", |
| |
| image: "postgres:15.4-bookworm", |
| pgupgrade+: { |
| enable: true, |
| from: "10", |
| }, |
| }, |
| bouncer: {}, |
| }, |
| |
| dataVolume: ns.Contain(kube.PersistentVolumeClaim("paperless-data")) { |
| storage:: "100Gi", |
| storageClass:: cfg.storageClassName, |
| }, |
| |
| deploy: ns.Contain(kube.Deployment(cfg.name)) { |
| spec+: { |
| replicas: 1, |
| template+: { |
| spec+: { |
| volumes_: { |
| data: top.dataVolume.volume, |
| }, |
| |
| 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: top.secretRefs.proxy.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: top.secretRefs.proxy.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: top.secretRefs.secret_key, |
| |
| A_REDIS_PASSWORD: top.redis.cfg.password, |
| PAPERLESS_REDIS: "redis://:$(A_REDIS_PASSWORD)@redis:6379", |
| |
| PAPERLESS_DBHOST: top.postgres.svc.host, |
| PAPERLESS_DBNAME: top.postgres.cfg.database, |
| PAPERLESS_DBUSER: top.postgres.cfg.username, |
| PAPERLESS_DBPASS: top.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_OCR_USER_ARGS: '{"continue_on_soft_render_error": true}', |
| 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: ns.Contain(kube.Service(cfg.name)) { |
| target:: top.deploy, |
| }, |
| |
| ingress: ns.Contain(kube.SimpleIngress(cfg.name)) { |
| hosts:: [cfg.domain], |
| target:: top.service, |
| }, |
| } |