{ pkgs, config, ... }: let containerStateDir = "/data"; hostStateDir = "/opt/documents/paperless"; httpPort = 80; paperlessPort = 8080; ftpListenPort = 20021; ftpPasvMinPort = 22021; ftpPasvMaxPort = 24021; domain = "paperless.local"; in { networking.firewall = { allowedTCPPorts = [ httpPort ftpListenPort ]; allowedTCPPortRanges = [ { from = ftpPasvMinPort; to = ftpPasvMaxPort; } ]; }; services.nginx = { enable = true; virtualHosts."${domain}" = { locations."/" = { proxyPass = "http://127.0.0.1:${toString paperlessPort}"; proxyWebsockets = true; extraConfig = '' proxy_read_timeout 300s; proxy_set_header Host ''$host; proxy_set_header X-Forwarded-For ''$remote_addr; ''; }; }; }; containers."paperless" = { autoStart = true; ephemeral = true; tmpfs = ["/tmp:size=2G"]; bindMounts."${containerStateDir}" = { hostPath = hostStateDir; isReadOnly = false; }; config = { config, pkgs, ... }: { networking.firewall.enable = false; users.users."paperless".extraGroups = ["ftp"]; services.paperless = { enable = true; dataDir = "/data"; consumptionDir = "/data/ftp/consume"; consumptionDirIsPublic = true; port = paperlessPort; extraConfig = { PAPERLESS_OCR_LANGUAGE = "deu+eng"; PAPERLESS_ALLOWED_HOSTS = "${domain}"; PAPERLESS_CSRF_TRUSTED_ORIGINS = "http://${domain}"; PAPERLESS_CORS_ALLOWED_HOSTS = "http://${domain}"; }; }; services.vsftpd = { enable = true; anonymousUser = true; anonymousUserNoPassword = true; anonymousUserHome = "/data/ftp"; anonymousUploadEnable = true; anonymousUmask = "007"; writeEnable = true; extraConfig = '' listen=YES listen_ipv6=NO listen_port=${toString ftpListenPort} chown_uploads=YES chown_username=paperless download_enable=NO pasv_min_port=${toString ftpPasvMinPort} pasv_max_port=${toString ftpPasvMaxPort} ''; }; systemd.services.nextcloud-autosync = { unitConfig = { Description = "Auto sync Nextcloud"; After = "network-online.target"; }; serviceConfig = { User = "paperless"; Type = "simple"; ExecStart = "${pkgs.nextcloud-client}/bin/nextcloudcmd -h -n --path Documents/_paperless /data/media/documents https://data.gssws.de"; TimeoutStopSec = "180"; KillMode = "process"; KillSignal = "SIGINT"; }; wantedBy = ["multi-user.target"]; }; systemd.timers.nextcloud-autosync = { unitConfig.Description = "Automatic sync files with Nextcloud when booted up after 5 minutes then rerun every 60 minutes"; timerConfig.OnUnitActiveSec = "60min"; wantedBy = ["multi-user.target" "timers.target"]; }; }; }; }