all repos — nixfiles @ 6c5f0f72ef513e4ab8a6669fe07677320f606eff

System and user configuration, managed by nix and home-manager

system/roles/paperless.nix (view raw)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
{
  config,
  lib,
  pkgs,
  ...
}:
let
  cfg = config.services.paperless;
  hostname = config.networking.hostName;
  ts-domain = "fin-marlin.ts.net";
in
{
  age.secrets = {
    cifs-paperless.file = ../../secrets/cifs-paperless.age;
    paperless = {
      file = ../../secrets/paperless.age;
      path = "${cfg.dataDir}/nixos-paperless-secret-key";
      owner = cfg.user;
      mode = "400";
      symlink = false;
    };
  };

  fileSystems."/srv/paperless" = {
    device = "//u439959-sub3.your-storagebox.de/u439959-sub3";
    fsType = "smb3";
    options =
      let
        # prevents hanging on network split
        automount_opts = [
          "x-systemd.automount"
          "noauto"
          "x-systemd.mount-timeout=5s"
        ];
        uid = config.ids.uids.paperless;
      in
      automount_opts
      ++ [
        "credentials=${config.age.secrets.cifs-paperless.path}"
        "seal"
        "multichannel"
        "nobrl" # needed for sqlite
        "forceuid"
        "forcegid"
        "uid=${toString uid}"
        "gid=${toString uid}"
      ];
  };
  services.paperless = {
    enable = true;
    address = "::1";
    mediaDir = "/srv/paperless/media";
    settings = {
      PAPERLESS_DBENGINE = "sqlite";
      PAPERLESS_TIME_ZONE = config.time.timeZone;

      PAPERLESS_URL = "https://papers.${ts-domain}";
      PAPERLESS_TRUSTED_PROXIES = "::1";
      PAPERLESS_USE_X_FORWARD_HOST = true;
      PAPERLESS_USE_X_FORWARD_PORT = true;
      PAPERLESS_PROXY_SSL_HEADER = [
        "HTTP_X_FORWARDED_PROTO"
        "https"
      ];
      PAPERLESS_ENABLE_COMPRESSION = false; # let caddy do it

      PAPERLESS_ENABLE_HTTP_REMOTE_USER = true;
      PAPERLESS_ENABLE_HTTP_REMOTE_USER_API = true;

      PAPERLESS_OCR_SKIP_ARCHIVE_FILE = "with_text";
      PAPERLESS_OCR_LANGUAGE = "deu+eng";
      PAPERLESS_IGNORE_DATES = "09.08.90";

      PAPERLESS_TASK_WORKERS = 2;
      PAPERLESS_THREADS_PER_WORKER = 1;
      PAPERLESS_NUMBER_OF_SUGGESTED_DATES = 4;

      PAPERLESS_CONSUMER_IGNORE_PATTERN = [
        ".DS_STORE/*"
        "desktop.ini"
        ".stfolder/*"
        ".stversions/*"
      ];

      PAPERLESS_FILENAME_FORMAT = "{correspondent}/{created} {title} {asn}";
      PAPERLESS_FILENAME_FORMAT_REMOVE_NONE = true;
    };
  };

  services.caddy.virtualHosts = {
    "papers.${ts-domain}" = {
      extraConfig = ''
        bind tailscale/papers
        tailscale_auth
        reverse_proxy [::1]:${toString config.services.paperless.port} {
          header_up Remote-User {http.auth.user.tailscale_login}
        }
      '';
    };
  };

  users.groups.paperless.members = [
    "alin"
    "syncthing"
  ];

  systemd.services.backup-paperless = {
    startAt = "daily";
    path = with pkgs; [
      openssh
    ];
    serviceConfig = {
      Type = "oneshot";
      WorkingDirectory = config.services.paperless.dataDir;
      ExecStart = [
        "systemd-run --machine=papers sudo -u paperless ./paperless-manage document_exporter --delete --use-filename-format --no-archive --no-thumbnail --no-progress-bar ./export  "
        "${lib.getExe pkgs.rdiff-backup} --api-version 201 backup /srv/paperless/export ${hostname}@r5.${ts-domain}::paperless"
      ];
      ExecStartPost = "-${lib.getExe pkgs.rdiff-backup} --api-version 201 remove increments --older-than 3M ${hostname}@r5.${ts-domain}::paperless";
    };
  };
}