This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

configs.services.paperless: init on neoprism

Paperless-ngx at https://paperless.lassul.us, behind nginx with ACME
(client_max_body_size 100M for phone photo uploads). OCR in German and
English; the nixpkgs module builds tesseract with the languages from
PAPERLESS_OCR_LANGUAGE. Data stays at the module's default
/var/lib/paperless (static paperless user, no DynamicUser) with SQLite.

Login via Zitadel (id.lassul.us): lass.zitadel project "paperless" with
access = "declarative", so only users granted on the project (by
verified email) can log in. allauth's openid_connect provider keys
social accounts by uid_field, set explicitly to the token's sub.
paperless' environmentFile is a single env file and the client secret
has to sit inside the PAPERLESS_SOCIALACCOUNT_PROVIDERS JSON, so the
paperless-oidc-env oneshot builds it from zitadel-reconcile's env file
into /run/paperless-oidc, keeping the secret out of the store.
The regular login form is disabled; DRF token and basic auth do not go
through allauth's pre_authenticate, so API tokens keep working. The
admin password comes from the paperless-admin vars generator via the
module's passwordFile (LoadCredential).

Backups: /var/lib/paperless plus a consistent .backup of its WAL-mode
SQLite database (the live db files are excluded).

Mailbox scan@lassul.us with a vars-generated password
(mailserver-scan) for paperless' IMAP mail fetching, configured later
in paperless' database.

DNS: paperless CNAME neoprism like the other neoprism services; Gatus
checks the login page.

+129
+19
configs/mailserver.nix
··· 67 67 "hermes@lassul.us" = { 68 68 hashedPasswordFile = config.clan.core.vars.generators.hermes-mail.files."password-hash".path; 69 69 }; 70 + # Fetched by paperless (configs/services/paperless) via IMAP. 71 + "scan@lassul.us" = { 72 + hashedPasswordFile = config.clan.core.vars.generators.mailserver-scan.files."password-hash".path; 73 + }; 70 74 }; 71 75 72 76 # TLS via existing ACME cert ··· 141 145 142 146 # the plaintext is read by zitadel-reconcile (root) 143 147 clan.core.vars.generators.mailserver-id = { 148 + files."password" = { }; 149 + files."password-hash" = { }; 150 + runtimeInputs = with pkgs; [ 151 + coreutils 152 + mkpasswd 153 + pwgen 154 + ]; 155 + script = '' 156 + pwgen -s 32 1 | tr -d '\n' > "$out/password" 157 + mkpasswd -sm bcrypt < "$out/password" > "$out/password-hash" 158 + ''; 159 + }; 160 + 161 + # the plaintext goes into paperless' mail account (root-only on neoprism) 162 + clan.core.vars.generators.mailserver-scan = { 144 163 files."password" = { }; 145 164 files."password-hash" = { }; 146 165 runtimeInputs = with pkgs; [
+1
configs/dns/lassul.us.zone
··· 68 68 ;; DNS-01 for the *.review wildcard cert, dynamic zone in knot.nix 69 69 _acme-challenge.review IN NS ns1 70 70 when IN CNAME neoprism 71 + paperless IN CNAME neoprism 71 72 72 73 ;; Mail 73 74 @ IN MX 3 mail
+1
configs/monitoring/checks.nix
··· 53 53 (https "byoidc" "https://byoidc.lassul.us/healthz") 54 54 (https "paint" "https://paint.lassul.us/") 55 55 (https "ntfy" "https://ntfy.lassul.us/v1/health") 56 + (https "paperless" "https://paperless.lassul.us/accounts/login/") 56 57 (https "cache" "https://cache.lassul.us/nix-cache-info") 57 58 (https "niks3" "https://niks3.lassul.us/health") 58 59 (soa "ns1" "95.217.192.59")
+8
machines/neoprism/backup.nix
··· 38 38 # WBO boards (paint.lassul.us). DynamicUser + StateDirectory make 39 39 # /var/lib/whitebophir only a symlink, so back up the real directory. 40 40 "/var/lib/private/whitebophir" 41 + # paperless (paperless.lassul.us) documents, index and classifier; the 42 + # SQLite database is dumped consistently to /var/backup by the preHook. 43 + "/var/lib/paperless" 41 44 ]; 42 45 exclude = [ 43 46 "*.pyc" ··· 45 48 "/home/bot/.nix-defexpr" 46 49 "/home/bot/.nix-profile" 47 50 "/var/lib/parley/*.db*" 51 + "/var/lib/paperless/db.sqlite3*" 48 52 ]; 49 53 repo = "u550643@u550643.your-storagebox.de:/./neoprism"; 50 54 encryption.mode = "none"; ··· 65 69 "/var/lib/hedgedoc" 66 70 # WAL-mode SQLite readers need to write the -shm file 67 71 "/var/lib/parley" 72 + "/var/lib/paperless" 68 73 ]; 69 74 70 75 preHook = '' ··· 94 99 for db in parley history; do 95 100 ${pkgs.sqlite}/bin/sqlite3 -cmd ".timeout 60000" "/var/lib/parley/$db.db" ".backup /var/backup/parley/$db.db" 96 101 done 102 + 103 + # Dump paperless SQLite database safely 104 + ${pkgs.sqlite}/bin/sqlite3 -cmd ".timeout 60000" /var/lib/paperless/db.sqlite3 ".backup /var/backup/paperless.sqlite3" 97 105 98 106 # Dump timeful polls (when.lassul.us) from MongoDB 99 107 ${pkgs.mongodb-tools}/bin/mongodump --uri=mongodb://127.0.0.1:27017 \
+1
machines/neoprism/config.nix
··· 25 25 ../../configs/services/pad 26 26 ../../configs/services/paint 27 27 ../../configs/services/ntfy 28 + ../../configs/services/paperless 28 29 29 30 ../../configs/hass/proxy.nix 30 31 ../../configs/hermes-proxy.nix
+99
configs/services/paperless/default.nix
··· 1 + { config, pkgs, ... }: 2 + let 3 + domain = "paperless.lassul.us"; 4 + cfg = config.services.paperless; 5 + zitadelEnv = config.lass.zitadel.projects.paperless.apps.web.envFile.path; 6 + oidcEnv = "/run/paperless-oidc/oidc.env"; 7 + paperlessServices = [ 8 + "paperless-secret-key.service" 9 + "paperless-scheduler.service" 10 + "paperless-task-queue.service" 11 + "paperless-consumer.service" 12 + "paperless-web.service" 13 + ]; 14 + in 15 + { 16 + clan.core.vars.generators.paperless-admin = { 17 + files."password" = { }; 18 + runtimeInputs = with pkgs; [ 19 + coreutils 20 + pwgen 21 + ]; 22 + script = '' 23 + pwgen -s 32 1 | tr -d '\n' > "$out/password" 24 + ''; 25 + }; 26 + 27 + services.paperless = { 28 + enable = true; 29 + inherit domain; 30 + passwordFile = config.clan.core.vars.generators.paperless-admin.files."password".path; 31 + environmentFile = oidcEnv; 32 + settings = { 33 + PAPERLESS_OCR_LANGUAGE = "deu+eng"; 34 + PAPERLESS_TIME_ZONE = "Europe/Berlin"; 35 + PAPERLESS_APPS = "allauth.socialaccount.providers.openid_connect"; 36 + PAPERLESS_SOCIAL_AUTO_SIGNUP = true; 37 + # only the login form; API tokens and basic auth keep working 38 + PAPERLESS_DISABLE_REGULAR_LOGIN = true; 39 + }; 40 + }; 41 + 42 + # Zitadel (id.lassul.us) login, only for users with a grant on the project. 43 + # zitadel-reconcile writes the client id/secret to zitadelEnv. 44 + lass.zitadel.projects.paperless = { 45 + access = "declarative"; 46 + users = [ "lass@lassul.us" ]; 47 + apps.web = { 48 + redirectUris = [ "https://${domain}/accounts/oidc/zitadel/login/callback/" ]; 49 + authMethod = "post"; 50 + }; 51 + }; 52 + 53 + # Builds PAPERLESS_SOCIALACCOUNT_PROVIDERS with the client secret into 54 + # oidcEnv, the paperless environmentFile. Accounts are keyed by `sub`. 55 + systemd.services.paperless-oidc-env = { 56 + wants = [ "zitadel-reconcile.service" ]; 57 + after = [ "zitadel-reconcile.service" ]; 58 + before = paperlessServices; 59 + requiredBy = paperlessServices; 60 + path = [ pkgs.jq ]; 61 + serviceConfig = { 62 + Type = "oneshot"; 63 + RemainAfterExit = true; 64 + RuntimeDirectory = "paperless-oidc"; 65 + RuntimeDirectoryMode = "0700"; 66 + RuntimeDirectoryPreserve = true; 67 + UMask = "0077"; 68 + EnvironmentFile = zitadelEnv; 69 + }; 70 + script = '' 71 + providers=$(jq -nc '{openid_connect: {APPS: [{ 72 + provider_id: "zitadel", 73 + name: "lassul.us ID", 74 + client_id: env.CLIENT_ID, 75 + secret: env.CLIENT_SECRET, 76 + settings: { 77 + server_url: "https://id.lassul.us", 78 + token_auth_method: "client_secret_post", 79 + uid_field: "sub" 80 + } 81 + }]}}') 82 + printf "PAPERLESS_SOCIALACCOUNT_PROVIDERS='%s'\n" "$providers" > ${oidcEnv}.tmp 83 + mv ${oidcEnv}.tmp ${oidcEnv} 84 + ''; 85 + }; 86 + 87 + services.nginx.virtualHosts.${domain} = { 88 + enableACME = true; 89 + forceSSL = true; 90 + locations."/" = { 91 + proxyPass = "http://${cfg.address}:${toString cfg.port}"; 92 + recommendedProxySettings = true; 93 + proxyWebsockets = true; 94 + extraConfig = '' 95 + client_max_body_size 100M; 96 + ''; 97 + }; 98 + }; 99 + }