summary refs log tree commit diff stats
path: root/system/linde.nix
diff options
context:
space:
mode:
Diffstat (limited to 'system/linde.nix')
-rw-r--r--system/linde.nix162
1 files changed, 128 insertions, 34 deletions
diff --git a/system/linde.nix b/system/linde.nix
index 2ca59842..da353bde 100644
--- a/system/linde.nix
+++ b/system/linde.nix
@@ -45,6 +45,9 @@ in
     dex.file = ../secrets/dex.age;
     powerdns.file = ../secrets/powerdns.age;
     redis-website.file = ../secrets/redis-website.age;
+    photoprism.file = ../secrets/photoprism.age;
+    cifs-photoprism.file = ../secrets/cifs-photoprism.age;
+    cifs-paperless.file = ../secrets/cifs-paperless.age;
     golink = let golink = config.services.golink; in {
       # hope this doesn't collide...
       path = "${golink.dataDir}/.config/tsnet-golink/auth.key";
@@ -64,10 +67,10 @@ in
 
   i18n.defaultLocale = "en_GB.UTF-8";
 
-  environment.enableAllTerminfo = true;
   environment.homeBinInPath = true;
   environment.localBinInPath = true;
   environment.systemPackages = with pkgs; [
+    cifs-utils
     htop
     lsof
     powerdns
@@ -99,14 +102,14 @@ in
     dates = "02:10";
     randomizedDelaySec = "59 min";
     allowReboot = true;
-    flake = "git+file://${config.services.gitolite.dataDir}/repositories/nixfiles.git";
+    flake = "git+file://${config.services.gitolite.dataDir}/repositories/nixfiles.git?submodules=1";
     flags = [
       "--no-write-lock-file"
       "--impure"
       "--update-input"
-      "nixpkgs-small"
+      "--nixpkgs"
       "--update-input"
-      "searchix"
+      "nixpkgs-small"
     ];
   };
 
@@ -152,8 +155,8 @@ in
       "1.0.0.1"
     ];
     hosts = lib.mkForce {
-      ${net-ip4} = [ "${hostname}.alanpearce.eu" hostname ];
-      ${net-ip6} = [ "${hostname}.alanpearce.eu" hostname ];
+      ${net-ip4} = [ "${hostname}.${domain}" hostname ];
+      ${net-ip6} = [ "${hostname}.${domain}" hostname ];
       ${net-rdnsip} = [ "dns" ];
       ${net-redisip} = [ "redis" ];
     };
@@ -297,7 +300,6 @@ in
       set --universal fish_greeting ""
     '';
   };
-  programs.zsh.enable = true;
   users.users.root = {
     shell = "/run/current-system/sw/bin/fish";
     openssh.authorizedKeys.keys = [
@@ -582,8 +584,8 @@ in
       openssh
     ];
     script = ''
-      rdiff-backup --api-version 201 backup ${config.services.gitolite.dataDir} ${hostname}@home.alanpearce.eu::gitolite
-      rdiff-backup --api-version 201 remove increments --older-than 3M ${hostname}@home.alanpearce.eu::gitolite
+      rdiff-backup --api-version 201 backup ${config.services.gitolite.dataDir} ${hostname}@nano.${ts-domain}::gitolite
+      rdiff-backup --api-version 201 remove increments --older-than 3M ${hostname}@nano.${ts-domain}::gitolite
     '';
     serviceConfig.Type = "oneshot";
   };
@@ -596,9 +598,9 @@ in
       openssh
     ];
     script = ''
-      sudo -u paperless ./paperless-manage document_exporter --delete --use-filename-format --no-archive --no-thumbnail --no-progress-bar ./export
-      rdiff-backup --api-version 201 backup ./export ${hostname}@home.alanpearce.eu::paperless
-      rdiff-backup --api-version 201 remove increments --older-than 3M ${hostname}@home.alanpearce.eu::paperless
+      systemd-run --machine=papers sudo -u paperless ./paperless-manage document_exporter --delete --use-filename-format --no-archive --no-thumbnail --no-progress-bar ./export
+      rdiff-backup --api-version 201 backup /srv/paperless/export ${hostname}@nano.${ts-domain}::paperless
+      rdiff-backup --api-version 201 remove increments --older-than 3M ${hostname}@nano.${ts-domain}::paperless
     '';
     serviceConfig = {
       Type = "oneshot";
@@ -783,6 +785,21 @@ in
             file_server
           '';
         };
+        "photos.alanpearce.eu" =
+          let
+            srv = config.services.photoprism;
+          in
+          {
+            useACMEHost = "alanpearce.eu";
+            extraConfig = ''
+              encode zstd gzip
+              ${security-headers {}}
+              reverse_proxy ${srv.address}:${toString srv.port}
+              handle_errors {
+                respond "{err.status_code} {err.status_text}"
+              }
+            '';
+          };
       };
   };
   systemd.services.caddy.serviceConfig = {
@@ -802,15 +819,41 @@ in
     home = "/srv/paperless";
   };
   users.groups.paperless.members = [ "alan" "syncthing" ];
+
+  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.idle-timeout=1h"
+          "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}"
+      ];
+  };
   containers.papers =
     let
-      hostDataDir = config.users.users.paperless.home;
+      externalDir = "/srv/paperless";
       localAddress6 = "fc00::2";
       tsHostname = "papers.${ts-domain}";
       tsPort = 41642;
+      hostConfig = config;
     in
     {
-      # or maybe socket activated?
       autoStart = true;
       # does TS need this?
       enableTun = true;
@@ -822,11 +865,15 @@ in
       }];
       bindMounts = {
         ${config.services.paperless.dataDir} = {
-          hostPath = hostDataDir;
+          hostPath = hostConfig.services.paperless.dataDir;
+          isReadOnly = false;
+        };
+        ${externalDir} = {
+          hostPath = externalDir;
           isReadOnly = false;
         };
       };
-      config = {
+      config = { config, lib, pkgs, ... }: {
         environment.systemPackages = with pkgs; [
           lsof
         ];
@@ -835,7 +882,7 @@ in
           resolvconf.enable = false;
           firewall.trustedInterfaces = [ "tailscale0" ];
           firewall.rejectPackets = true;
-          nameservers = config.networking.nameservers;
+          nameservers = hostConfig.networking.nameservers;
         };
         services.resolved = {
           enable = true;
@@ -894,6 +941,7 @@ in
         services.paperless = {
           enable = true;
           address = "[::1]";
+          mediaDir = "${externalDir}/media";
           settings = {
             PAPERLESS_DBENGINE = "sqlite";
             PAPERLESS_TIME_ZONE = "Europe/Berlin";
@@ -926,15 +974,13 @@ in
       };
     };
 
-  services.etcd = {
-    enable = true;
-    initialClusterState = "existing";
-    dataDir = "/var/lib/etcd"; # TODO backup
-    extraConf = {
-      AUTO_COMPACTION_RETENTION = "1h";
-    };
+  users.users.dex = {
+    home = "/var/lib/dex";
+    createHome = true;
+    isSystemUser = true;
+    group = "dex";
   };
-
+  users.groups.dex = { };
   services.dex =
     let
       issuer = "https://id.alanpearce.eu/";
@@ -945,11 +991,8 @@ in
       settings = {
         inherit issuer;
         storage = {
-          type = "etcd";
-          config = {
-            endpoints = config.services.etcd.listenClientUrls;
-            namespace = "dex/";
-          };
+          type = "sqlite3";
+          config.file = "/var/lib/dex/storage.sqlite";
         };
         web.http = "127.0.0.1:5556";
         connectors = [{
@@ -977,10 +1020,16 @@ in
         ];
       };
     };
-  systemd.services.dex.unitConfig = {
-    After = [ "etcd.service" ];
-    Requires = [ "etcd.service" ];
-  };
+  systemd.services.dex.serviceConfig =
+    let
+      user = config.users.users.dex;
+    in
+    {
+      ReadWritePaths = [ user.home ];
+      DynamicUser = lib.mkForce false;
+      User = user.name;
+      Group = user.group;
+    };
 
   services.redis = {
     servers = {
@@ -1124,4 +1173,49 @@ in
       default = [{ type = "insecureAcceptAnything"; }];
     };
   };
+
+  fileSystems."/srv/photoprism" = {
+    device = "//u439959-sub1.your-storagebox.de/u439959-sub1";
+    fsType = "smb3";
+    options =
+      let
+        # prevents hanging on network split
+        automount_opts = [
+          "x-systemd.automount"
+          "noauto"
+          "x-systemd.idle-timeout=1h"
+          "x-systemd.mount-timeout=5s"
+        ];
+        uid = 64600;
+      in
+      automount_opts ++ [
+        "credentials=${config.age.secrets.cifs-photoprism.path}"
+        "seal"
+        "multichannel"
+        "nobrl" # needed for sqlite
+        "forceuid"
+        "forcegid"
+        "uid=${toString uid}"
+        "gid=${toString uid}"
+      ];
+  };
+  services.photoprism = {
+    enable = true;
+    passwordFile = config.age.secrets.photoprism.path;
+    originalsPath = "/srv/photoprism/originals";
+    importPath = "/srv/photoprism/import";
+    settings = {
+      PHOTOPRISM_SITE_URL = "https://photos.alanpearce.eu";
+      PHOTOPRISM_SITE_CAPTION = "Alan‘s Photos";
+      PHOTOPRISM_DISABLE_TLS = "true";
+      PHOTOPRISM_SIDECAR_PATH = "/srv/photoprism/sidecar";
+      PHOTOPRISM_SPONSOR = "true";
+    };
+  };
+  systemd.services.photoprism = {
+    unitConfig.RequiresMountsFor = "/srv/photoprism";
+    serviceConfig.ReadWritePaths = [
+      "/srv/photoprism/sidecar"
+    ];
+  };
 }