From 5f3b25b4dfa16b10ac906df9cff747384c1bd16b Mon Sep 17 00:00:00 2001
From: notohh <github@notohh.dev>
Date: Tue, 18 Feb 2025 08:17:45 -0500
Subject: [PATCH] yuki: init hoarder && immich && remove unused services

sops: update secrets
---
 hosts/yuki/hardware.nix                   |   8 ++
 hosts/yuki/services/default.nix           |   5 +-
 hosts/yuki/services/hoarder.nix           |  36 +++++++
 hosts/yuki/services/homepage/default.nix  |   6 +-
 hosts/yuki/services/homepage/services.nix | 113 ++++------------------
 hosts/yuki/services/hydroxide.nix         |  17 ----
 hosts/yuki/services/immich.nix            |  17 ++++
 hosts/yuki/services/paperless.nix         |  34 -------
 hosts/yuki/services/searxng.nix           |  52 ----------
 hosts/yuki/services/traefik.nix           |  25 +++++
 secrets/homepage/secrets.yaml             |   8 +-
 secrets/secrets.yaml                      |   6 +-
 12 files changed, 119 insertions(+), 208 deletions(-)
 create mode 100644 hosts/yuki/services/hoarder.nix
 delete mode 100644 hosts/yuki/services/hydroxide.nix
 create mode 100644 hosts/yuki/services/immich.nix
 delete mode 100644 hosts/yuki/services/paperless.nix
 delete mode 100644 hosts/yuki/services/searxng.nix

diff --git a/hosts/yuki/hardware.nix b/hosts/yuki/hardware.nix
index fd0c8a9..365ded2 100644
--- a/hosts/yuki/hardware.nix
+++ b/hosts/yuki/hardware.nix
@@ -43,6 +43,14 @@
       device = "192.168.1.199:/mnt/Sutoreji/paperless-ngx/paperless-media ";
       fsType = "nfs";
     };
+    "/var/lib/hoarder" = {
+      device = "192.168.1.199:/mnt/Sutoreji/hoarder ";
+      fsType = "nfs";
+    };
+    "/var/lib/immich" = {
+      device = "192.168.1.199:/mnt/Sutoreji/immich ";
+      fsType = "nfs";
+    };
   };
 
   swapDevices = [
diff --git a/hosts/yuki/services/default.nix b/hosts/yuki/services/default.nix
index 8f87309..760a480 100644
--- a/hosts/yuki/services/default.nix
+++ b/hosts/yuki/services/default.nix
@@ -7,10 +7,9 @@
     ./stash.nix
     ./jellyfin.nix
     ./wallos.nix
-    # ./searxng.nix
     ./anki-sync-server.nix
-    # ./paperless.nix
-    # ./hydroxide.nix
+    ./hoarder.nix
+    ./immich.nix
     # ./botoh.nix
   ];
 }
diff --git a/hosts/yuki/services/hoarder.nix b/hosts/yuki/services/hoarder.nix
new file mode 100644
index 0000000..98299f1
--- /dev/null
+++ b/hosts/yuki/services/hoarder.nix
@@ -0,0 +1,36 @@
+{config, ...}: {
+  sops.secrets.hoarder = {};
+  services.meilisearch = {
+    enable = true;
+    listenAddress = "0.0.0.0";
+  };
+  virtualisation.oci-containers.containers = {
+    hoarder-web = {
+      image = "ghcr.io/hoarder-app/hoarder@sha256:e2156f3de4a1eafc53afb6e682f20857be4449d7e9d24240afe6d9ccd280ed3b";
+      ports = ["3000:3000"];
+      environment = {
+        BROWSER_WEB_URL = "http://localhost:9222";
+        DATA_DIR = "/data";
+        DISABLE_SIGNUPS = "true";
+        MEILI_ADDR = "http://localhost:${toString config.services.meilisearch.listenPort}";
+        OCR_LANGS = "eng";
+      };
+      volumes = ["/var/lib/hoarder:/data"];
+      environmentFiles = [/run/secrets/hoarder];
+      extraOptions = ["--network=host"];
+    };
+    hoarder-chrome = {
+      image = "gcr.io/zenika-hub/alpine-chrome";
+      cmd = [
+        "--no-sandbox"
+        "--disable-gpu"
+        "--disable-dev-shm-usage"
+        "--remote-debugging-address=0.0.0.0"
+        "--remote-debugging-port=9222"
+        "--hide-scrollbars"
+      ];
+      ports = ["9222:9222"];
+      extraOptions = ["--network=host"];
+    };
+  };
+}
diff --git a/hosts/yuki/services/homepage/default.nix b/hosts/yuki/services/homepage/default.nix
index 86e42e5..074d3df 100644
--- a/hosts/yuki/services/homepage/default.nix
+++ b/hosts/yuki/services/homepage/default.nix
@@ -27,7 +27,7 @@
       statusStyle = "dot";
       hideVersion = true;
       background = {
-        image = "https://i.imgur.com/Q8xIWP7.png";
+        image = "https://git.flake.sh/notohh/assets/raw/branch/main/wallpapers/miku/miku.png";
         brightness = 75;
       };
       providers = {
@@ -71,9 +71,9 @@
           };
         }
         {
-          "Storage" = {
+          "Misc apps" = {
             style = "row";
-            columns = 1;
+            columns = 2;
           };
         }
         {
diff --git a/hosts/yuki/services/homepage/services.nix b/hosts/yuki/services/homepage/services.nix
index ff1f80b..e02a17f 100644
--- a/hosts/yuki/services/homepage/services.nix
+++ b/hosts/yuki/services/homepage/services.nix
@@ -234,39 +234,6 @@ _: {
             };
           };
         }
-        {
-          "Readarr" = {
-            icon = "readarr";
-            href = "https://readarr.internal.flake.sh";
-            widget = {
-              type = "readarr";
-              url = "${kariruIp}8787";
-              key = "{{HOMEPAGE_VAR_READARR_KEY}}";
-            };
-          };
-        }
-        {
-          "Lidarr" = {
-            icon = "lidarr";
-            href = "https://lidarr.internal.flake.sh";
-            widget = {
-              type = "lidarr";
-              url = "${kariruIp}8686";
-              key = "{{HOMEPAGE_VAR_LIDARR_KEY}}";
-            };
-          };
-        }
-        {
-          "Bazarr" = {
-            icon = "bazarr";
-            href = "https://bazarr.internal.flake.sh";
-            widget = {
-              type = "bazarr";
-              url = "${kariruIp}6767";
-              key = "{{HOMEPAGE_VAR_BAZARR_KEY}}";
-            };
-          };
-        }
         {
           "Prowlarr" = {
             icon = "prowlarr";
@@ -301,6 +268,17 @@ _: {
             };
           };
         }
+        {
+          "immich" = {
+            icon = "immich";
+            href = "https://immich.internal.flake.sh";
+            widget = {
+              type = "immich";
+              url = "http://192.168.1.98:2283";
+              key = "{{HOMEPAGE_VAR_IMMICH_KEY}}";
+            };
+          };
+        }
         {
           "Whisparr" = {
             icon = "whisparr";
@@ -315,51 +293,6 @@ _: {
         }
       ];
     }
-    {
-      "Storage" = [
-        {
-          "Nextcloud" = {
-            icon = "nextcloud";
-            href = "https://nextcloud.internal.flake.sh:9001";
-            widget = {
-              type = "nextcloud";
-              url = "https://192.168.1.199:9001";
-              username = "notoh";
-              password = "{{HOMEPAGE_VAR_NEXTCLOUD_PWD}}";
-            };
-          };
-        }
-        {
-          "Synology" = {
-            icon = "synology";
-            href = "https://synology.internal.flake.sh:5001/";
-            widget = {
-              type = "diskstation";
-              url = "https://192.168.1.71:5001";
-              username = "homepage";
-              password = "{{HOMEPAGE_VAR_SYNOLOGY_PWD}}";
-            };
-          };
-        }
-        {
-          "Paperless-ngx" = {
-            icon = "paperless-ngx";
-            href = "https://paperless.internal.flake.sh";
-            widget = {
-              type = "paperlessngx";
-              url = "http://100.108.113.89:28981";
-              key = "{{HOMEPAGE_VAR_PAPERLESS_KEY}}";
-            };
-          };
-        }
-        {
-          "Minio" = {
-            icon = "minio";
-            href = "http://100.69.79.81:9006/browser/";
-          };
-        }
-      ];
-    }
     {
       "Misc" = [
         {
@@ -374,18 +307,6 @@ _: {
             href = "https://accounts.hetzner.com/login";
           };
         }
-        {
-          "Backblaze" = {
-            icon = "backblaze";
-            href = "https://secure.backblaze.com";
-          };
-        }
-        {
-          "notohh.dev" = {
-            icon = "hugo";
-            href = "https://notohh.dev/";
-          };
-        }
         {
           "Stash" = {
             icon = "stash";
@@ -405,9 +326,9 @@ _: {
           };
         }
         {
-          "Hedgedoc" = {
-            icon = null;
-            href = "https://scratch.flake.sh";
+          "Hoarder" = {
+            icon = "hoarder";
+            href = "https://hoarder.internal.flake.sh";
           };
         }
         {
@@ -416,6 +337,12 @@ _: {
             href = "https://wallos.internal.flake.sh";
           };
         }
+        {
+          "Ganymede" = {
+            icon = null;
+            href = "https://ganymede.internal.flake.sh";
+          };
+        }
       ];
     }
   ];
diff --git a/hosts/yuki/services/hydroxide.nix b/hosts/yuki/services/hydroxide.nix
deleted file mode 100644
index 690332c..0000000
--- a/hosts/yuki/services/hydroxide.nix
+++ /dev/null
@@ -1,17 +0,0 @@
-{pkgs, ...}: {
-  environment.systemPackages = [pkgs.hydroxide];
-  networking.firewall.allowedTCPPorts = [1025 1143];
-
-  systemd.services.hydroxide = {
-    enable = true;
-    wantedBy = ["multi-user.target"];
-    description = "A third-party, open-source ProtonMail bridge";
-
-    serviceConfig = {
-      User = "notoh";
-      ExecStart = "${pkgs.hydroxide}/bin/hydroxide -disable-carddav serve";
-      Restart = "always";
-      RestartSec = 30;
-    };
-  };
-}
diff --git a/hosts/yuki/services/immich.nix b/hosts/yuki/services/immich.nix
new file mode 100644
index 0000000..ce0d20a
--- /dev/null
+++ b/hosts/yuki/services/immich.nix
@@ -0,0 +1,17 @@
+_: {
+  sops.secrets.immich = {};
+  services.immich = {
+    enable = true;
+    openFirewall = true;
+    host = "0.0.0.0";
+    mediaLocation = "/var/lib/immich";
+    secretsFile = "/run/secrets/immich";
+    machine-learning.enable = true;
+    redis = {
+      enable = true;
+    };
+    database = {
+      createDB = true;
+    };
+  };
+}
diff --git a/hosts/yuki/services/paperless.nix b/hosts/yuki/services/paperless.nix
deleted file mode 100644
index 73df8ef..0000000
--- a/hosts/yuki/services/paperless.nix
+++ /dev/null
@@ -1,34 +0,0 @@
-{
-  pkgs,
-  config,
-  lib,
-  ...
-}: {
-  sops.secrets.paperless-pwd = {
-    owner = "paperless";
-    group = "paperless";
-  };
-
-  systemd.services = {
-    paperless-task-queue.serviceConfig = {PrivateNetwork = false;};
-    paperless-scheduler.serviceConfig = {PrivateNetwork = lib.mkForce false;};
-  };
-
-  services.paperless = let
-    dataDir = "/var/lib/paperless-ngx";
-  in {
-    package = pkgs.paperless-ngx;
-    enable = true;
-    address = "0.0.0.0";
-    port = 28981;
-    passwordFile = config.sops.secrets.paperless-pwd.path;
-    dataDir = "${dataDir}";
-    mediaDir = "${dataDir}/media";
-    consumptionDir = "${dataDir}/consume";
-    settings = {
-      PAPERLESS_ADMIN_USER = "notoh";
-      PAPERLESS_REDIS = "redis://:paperless-ngx@192.168.1.211:6382";
-      PAPERLESS_EMAIL_TASK_CRON = "*/5 * * * *";
-    };
-  };
-}
diff --git a/hosts/yuki/services/searxng.nix b/hosts/yuki/services/searxng.nix
deleted file mode 100644
index c3a7bd2..0000000
--- a/hosts/yuki/services/searxng.nix
+++ /dev/null
@@ -1,52 +0,0 @@
-{
-  pkgs,
-  config,
-  ...
-}: {
-  sops.secrets.searxng-secret = {};
-  networking.firewall.allowedTCPPorts = [8100];
-  services.searx = {
-    package = pkgs.searxng;
-    enable = false;
-    runInUwsgi = false;
-    environmentFile = config.sops.secrets.searxng-secret.path;
-    limiterSettings = {
-      botdetection = {
-        ip_lists = {
-          pass_ip = [
-            "192.168.0.0/16"
-            "172.16.0.0/12"
-            "10.0.0.0/8"
-          ];
-        };
-      };
-    };
-    settings = {
-      general = {
-        debug = false;
-        instance_name = "SearXNG";
-      };
-      ui = {
-        default_theme = "simple";
-        theme_args = {
-          simple_style = "dark";
-        };
-      };
-      search = {
-        autocomplete = "google";
-        safe_search = 0;
-        default_lang = "en-US";
-      };
-      server = {
-        port = 8100;
-        bind_address = "0.0.0.0";
-        secret_key = "@SEARXNG_SECRET@";
-        public_instance = false;
-        infinite_scroll = true;
-      };
-      redis = {
-        url = "redis://:searxng@100.94.214.100:6380";
-      };
-    };
-  };
-}
diff --git a/hosts/yuki/services/traefik.nix b/hosts/yuki/services/traefik.nix
index 016b0b5..6147c63 100644
--- a/hosts/yuki/services/traefik.nix
+++ b/hosts/yuki/services/traefik.nix
@@ -128,6 +128,27 @@
             tls.domains = [{main = "*.${fqdn}";}];
             tls.certresolver = "production";
           };
+          ganymede = {
+            rule = "Host(`ganymede.${fqdn}`)";
+            entrypoints = ["websecure"];
+            service = "ganymede";
+            tls.domains = [{main = "*.${fqdn}";}];
+            tls.certresolver = "production";
+          };
+          hoarder = {
+            rule = "Host(`hoarder.${fqdn}`)";
+            entrypoints = ["websecure"];
+            service = "hoarder";
+            tls.domains = [{main = "*.${fqdn}";}];
+            tls.certresolver = "production";
+          };
+          immich = {
+            rule = "Host(`immich.${fqdn}`)";
+            entrypoints = ["websecure"];
+            service = "immich";
+            tls.domains = [{main = "*.${fqdn}";}];
+            tls.certresolver = "production";
+          };
         };
         services = let
           kariruHost = "192.168.1.54:";
@@ -141,6 +162,8 @@
           hass.loadBalancer.servers = [{url = "http://localhost:8123";}];
           paperless.loadBalancer.servers = [{url = "http://localhost:28981";}];
           miniflux.loadBalancer.servers = [{url = "http://localhost:9000";}];
+          hoarder.loadBalancer.servers = [{url = "http://localhost:3000";}];
+          immich.loadBalancer.servers = [{url = "http://localhost:2283";}];
           # kariru
           sonarr.loadBalancer.servers = [{url = "http://${kariruHost}8989";}];
           radarr.loadBalancer.servers = [{url = "http://${kariruHost}7878";}];
@@ -149,6 +172,8 @@
           bazarr.loadBalancer.servers = [{url = "http://${kariruHost}6767";}];
           whisparr.loadBalancer.servers = [{url = "http://${kariruHost}6969";}];
           prowlarr.loadBalancer.servers = [{url = "http://${kariruHost}9696";}];
+          # sakura
+          ganymede.loadBalancer.servers = [{url = "http://100.121.201.47:4000";}];
         };
       };
     };
diff --git a/secrets/homepage/secrets.yaml b/secrets/homepage/secrets.yaml
index 79e6b75..79a1cb2 100644
--- a/secrets/homepage/secrets.yaml
+++ b/secrets/homepage/secrets.yaml
@@ -1,4 +1,4 @@
-homepage-secrets: ENC[AES256_GCM,data:4a0UVT8No2ZqkF3oFG9BAB1JHFhHZneREU5yLLAm3lw2NP64vZy9uVYm8y+fHe9MzSVmDZQ3azIruXmDVhSkDR/R9RBcC9NUT0zw2axhuISzkdhxX8WZmjk2fZk3OhVwmt/F6Ja/rTGg7wfKNyPhygCTCCTOKxLo0xmpCHoIafkVJsX7OH/szs8Z5t3TTQxpc/qgodnkHyh27mVb8YCcbEvD35V6cbHKCJCaMTbTNksUM6ux8WxUKH9PUIUmLI9pFZSaYEuCba+jLMzmQK9XN30VP8IJW1spAJz10KGCSDHD7tqvwk+s7OWB3p/68tdH1t6lpoaYRwO9h5R+H7swPQiC70uhjQHVbufhKHYo+Q4f1vk2f+F4+AyNYuFC07iQvW5r+4QHHmdIQ50A8ngXG0/U2i6QKXUO6degeYTJZLa5q3o4/Rvwuadu+GCtTUq0rNRfP8cGohkDrQTi8DQMamjCVhB5CoXrMGhwhAkMznaHDfeg8pJAZrFjxl6mgeXVycjq5fnUNNrJciyuxUm34h1Hmp5mVgZ61vhrjkDib4jBEh1PdJFw/8zXD7GEAJQlAcNx0m6ES4MiZQezC7I6LDXXOvb+zTQYhXZhrQ3IeW03kjGiYK9qzUN3fzRB2k10mOuag1t7dNq32ogLwc+eIxhKsD2iKuSO6QbqFmo+myqMOP2aL6lre1mHiQ/Wb5OKwA3lmpWl97MHBlrWvYWCX17xFq0bY0xjh3K6HbkEx5yuHbLy9S4Re5h5VXg+LsAeamKMZSqsZjpPP7QcTRao5o6X8tvPsTSe8DPc9ZVmTNTVSzcLc/0M8hxLtemI6IbbXCgFp1tW0Yy7OEsX+3sfbBRi+vO2alv4hUynwEZVUpkfY9JSp94X89izNzJBdGbfbxsN6pzJG/qWqaxJkQF6VHK63aqvbZKicCf2j3WlJxBkVTofI8Pxw31g8XVFH/Bgs7gKClh1HClgVZU8F7nkQGu036rquK0tp+suyLcEKrChBBwjqgIeS/W7Gge3y8b5U1nTsW5+fpb9UKGxYQFLaoIYImyYTYafbkPeS4Xd3k/BcvG0TnPFBbfg4GNzvykZR+CFLQBwvC12j0fbPQQqR4yQXgrqZ/6rJYgyL69gkA7ih3fk3vYCvpdXpp5QJipLNzKoPhdaDN75rPzNssBPPWgj/9XaKofO5QY+frEZRoZVJBvpvgsX7oE+vcQpHMAWzN2aO8AU3N96MplQrEld633Sxa66+rSuXUvJ8kzOkwwhTSb17NjW5xuT5GcREnehFBIulMZmgEaLtpP2PM24r3Qld4QJuYmv1y8rq0YK4U0oweOFfGT+o2yHVrVkDMLqbDGHTOuNn/73Bwrs3kKsopPnBdxbnQa5ICuWYWCgYRCC+jjekp7AK8SyKG0HlbxrUbDUBsonrnbLTo0sSncRWPPCtASa+7NL2PwnKNMFI+bmi/RzXgePAt/YkCsTbtTr3lhqqRt9ychyafFx0PmWLGbqfNc+scS+RzRxzfhm0HUi37xOT0QTGCfQ0B1Na8phEyVCFFOVPvUyQYX4uFTMpsB3m+Q/pwIpTtU82NJu9cADkJ5lyhlHkyEZsCqYmBPb5UMCFn6bmA1efd+1sD72vFnCxoxZCPtAZFp4n7oA+5uv7zxr1np66qKLGymZkUuFGCb6ULdgooUvBYPy01rUA7MVkxBjVXfg8uH5Wtny/FaRFTnEEhxBrxIbExvLSM2y3Ilz53Yb/izSZyu+xcEe73wriTnAKZS+NEj4D7W6lnBIN/lXqWMkwncaoRR4wzHjYIinP2jA5/z2HqoDFBWelg6sLAbPRs/FbM8f6hWEiX5gj33EYmTxRyYnpkJVTwAoLYoJZi+KIeq+btSKg4XAaeInLIWEH0moMgBOMlDMhEOZTI+ELpd/tkLisgr8v7cPBgWknsotEaxVm9MPqylAREN0AC+YNJyI1ao=,iv:PM9br61pbXWJh4Ahf4kz1dTuNNWfmXty9bxMK4UJtUs=,tag:IHIrVQydW/+N9ZNdf32rXg==,type:str]
+homepage-secrets: ENC[AES256_GCM,data:Smj/q8KrsxupeezkfAuWVKLv+45o70rI5ll/DRv+gVkDZmEvtGRDeaTCQeaYv8Kl0cOjYvxGGd7IbwzZqmrvMNx7tpvJ1jPRhapuk19JsivFqVe68ZOzBrDEBuVMxe9s4PTP73SYjzuC/nTBnTWD9LbsRlBmWQxewi4elBvSZj1dDVuOamYZvYaGss+W1yMWoL9nWHoKOTthUZhEocwNKmqhZzDI1T8gHL2w/aMddG47rs2NGYatO69446aNO94g99Hl3rVEDlgmxzh7ZFbRRtznD+EYEgxb/j7rDZkjPHwaeShYPGQPF41zR9CgHRVuMUaPcyba/yGpKRLXvT2nNBH8lopEKWh3WzVPET0EksVnzLnzVh2wEFzm5gYgQOFxu83iuhhvo+RvaUY5CyRBYZyGePluXRTUnLLbPLb+ZNG00KmEkojm2Q+uRqimHgPEb9bfJYubCQ68vv828QllmTrGH9d6QbyxJIX4mwIlGtIhD5a9tpVD6Lwjn4V0/v9oV0QK3jxv/jwh7KfGeJYcFTlJTgIjpYwaAIjnBpm+KrhsHQ+94qsZYhMPIUyUZ/UN31cDAqD4ghflYGC47aQR5AfPJwacXdDDbs4cUl5duQYVY6HvsFsJ0OqGc7hYhOhLDzUXbgxVwQKVJjs5Q7XMySpt22HnQqJnrKoufMCTY0Fk8CUZ1BqNOiuG+b3SZoOLDXUvWyKUF7CrHKtRWp4ZYF17B0VMgaTluxI9FzWIQjgQXlApM5RAmVKxEDKxhHjqyvt9ZjCGwMblYdzuaL54W+7QprRWzSUIze2BALTeoCZCYVB7/9O1wmbGlh+rE6Wh4w7p4XoBaraRwnwW+eGjDzcR7+eXkE/SF+XvU5qJKPHT9Yd9XQu5cFM9TmVF0TVjsKsF8xGBU+njZuTLGT+/gv1hU2Uy5g6ng5MncJ8qWPoexhseDK/Rvdsi5E2NiFusyRiDcU/dBCVI0pswGrp1BkjmypWbMYsOKhEmI6zQZYMEAb9O8I+ch+PTnRwmQv6ZLSvr1oTPdsc/k8F4cP6eBiLew6tCwtoyw8RIKsZFgPu2Cuq+1IdBZe+hgw29Q1MZbErSsc2LNeoVBXyrXztljnOjyogMSX1c7OCcVDRFxXCzijB+/JA7PP8z6Viro9VnmqB+NjIxPF9j7zLyD1mdG1wde0YVPdD6sbxari9LYjONogx1QqkdjceQJ8ifQmSWgfAJHRuQTpV05iT7+AyTc6SdHh/fT6jIPccsvksRzRhvVGurLbdft4IwFBcVrcOTAHGpRezDIGubGeoNvLrTj2hZ7zDO9dfRm4pdMz5xaaX6gmz0F49u+iDjYja4bBzXTWK/cI0A7YuhNfzLj8qYrEosimM41zYoRczUR7N4SYcspRLk9/fHdpXrvMxOKhihPM6z2DQd+MyEWAKPeZQBeuZ95I/MfKnRe+by/hMzsljvyqFq+O4t0VdVXv5Ff4NxwWyIB58TzZxbG+saOYccaVr3USfDjxIwVzBO5KbmH02eKJFHNoJlYap/kwgq6Dp3ghUtfHdLHsOis36NTfN94WDLlmtpys9ifpIiky75i3FFjA2Pj98mCxJH6oWuprzi6kg5ikz3IgRMERh4/KcmCfeSc6CSAy22rNNEpgblMY+BCgMjEBk9/TPbKqoYBYlWsVjFEX7dvcupjbORLf5uj5JYe1PXk3yYw45N/6seV5fhds2aOwQCwNoQJfmKc9xTVSgy6h8GreX+E1UAhpphpbhwDFXYgJRAdMXz61iGYfoAnI3KXLZpn0jERldfFib1mZhEFhtkkUzo+1GPsInJy5aylBps3KQVC7K0SzEmkYaLgTQL5GPrVIG61xnKc1yz6XbrLTBUMVDxhGuOvbf7OpOe2SvIq2JmSp928jzFy/Zw,iv:jMmc5HCA+Y17u9GFpYaYFtZoZax7twHqO9bL2ZwYT58=,tag:+dlXYarEFLBOhOaVajSk4g==,type:str]
 sops:
     kms: []
     gcp_kms: []
@@ -14,8 +14,8 @@ sops:
             bGM5b1BLMTVlUDBDY0Z3L2dRbVZrb00Kj641oh4R7VfmWFmCaq5aRWcDTvzJvZBR
             aIJdMFJEB4B43dlv2/bLYsoFs8LJJ2CHu1my9/BlNI+345ZlrFpQgQ==
             -----END AGE ENCRYPTED FILE-----
-    lastmodified: "2024-03-14T09:47:50Z"
-    mac: ENC[AES256_GCM,data:gN727Lqzt6tbZNzSLAXtqGN3QzEILG774Z7FP/ytt8Ghh1KiCVEkuiO89u1eSe4AqnFYSJrV9w2ptc2mAaxCnlw7sTlAUv7mgv6tR4QIV2sh1d8WpQNqkkNf5mrWqXkRn6WXHPxW4vluoQYn3jH0PmKp8depX1zR8itVCW/3pjA=,iv:syhUh7Bk8K04inF2e5mYhhPb+LTIZd5uFSJ0rSZd+HE=,tag:Ck0P3YK9uIJleYMAQDhvDQ==,type:str]
+    lastmodified: "2025-02-18T13:15:16Z"
+    mac: ENC[AES256_GCM,data:phkczoGvho6Wa2TUmtc1YFHEOttCem8m4E68jcZXZiHrWpDhagZSA2fxssnb3Atz5PqdX3Q6omK4d1B3IZzh0BVCr+Nn9DbplU7+FXn0mmEPO5tdkeDS0IFD9cipVExRBlBZgM981GOsyU22xIVE7tlcyHNeXns8gevoW+i20QA=,iv:dRgBf4GLOvDI9Z9Lo6LhA6U+KUX9YRWnvpFo3DrwWdc=,tag:1xtCEQQHrlneqXpmAKu25g==,type:str]
     pgp: []
     unencrypted_suffix: _unencrypted
-    version: 3.8.1
+    version: 3.9.4
diff --git a/secrets/secrets.yaml b/secrets/secrets.yaml
index 4d01791..bde689e 100644
--- a/secrets/secrets.yaml
+++ b/secrets/secrets.yaml
@@ -17,6 +17,8 @@ vaultwarden-env: ENC[AES256_GCM,data:db5b1dqvHs86t1exBaymKU3bLh4JYy4oHwgU5kjrsay
 twitch_auth: ENC[AES256_GCM,data:jY3RBIWSGVQJVK2I1bJTxvNkt50ELGo9Dvsao9S2c1SnOWIqfkPLmch1X6cbWnLgS39qIgqCwCnnt3K+4Fo5OPSvCuEQULYBp+avK03z2rhnuq72N3qgg0nd34srQ99mwCELDEZu5bTzHmmWtzeByGdCOlo/DCm2wSykJaA/OzSrZ7SkudvsK9jV3cAQjZACAefU68OVxWYw8AS/LdHPf4ZuxCZC2TZIVg5wF5TLqzEluLCNNiov6kHsfJcrKIXZsWPciZr8w/ws29Pu0H0+dKqxRPQA+SB4qraUp2hWTbBnAhnrb6gG4Qb4dym3jj0wa3lopGV1JFM6KVT213tFE9MA4fBRDFaiisHOUEhEfQ==,iv:Ixj3aphsbBExbXp2ZXL393RZKok1+Yhx4JRbyAHajOI=,tag:Subi21WTz+kiu2X+Upjyew==,type:str]
 github-token: ENC[AES256_GCM,data:UkHqWyRX8Y3yjSuFehPCPfldT5/fWrh1Ssr8Tiv5Tj5Ce31C4nMZ1KOQXgXVEsh2yT+sBZKGhua+RxoCyKXup1LcEw==,iv:OjLk5Qgfx9Dw85oc18Rgr2SnMzK+vSvHpijt4/fweoY=,tag:8koHj5p4W53BUkJsgPtChw==,type:str]
 ganymede-auth: ENC[AES256_GCM,data:MfkXzZsA9u3D76zFLPeVDFedtns2yZ3ma0thUqsKO7rOHsisZbF4J0/as0zDJUgP+WLfI4ETY8b4krS+gsZO1JtAJ4sZGZT/ldWUY6bIzb6kxseS1AP2GOGHkpN1KEbeR8Lbsaga/99r8kOiABSV27EVnzMkT4K9YZFRm02UEEuCA5OKqmdcj4SetQ2Ef0i4AIhwUTSNU2kQbY+V9WAwNf6JAgV1aMk/OFmz9udXmn59DvpsTERf9KnC,iv:VcJCbd4bHBmZqFY3dG/B8L/9uzW9uPzdeWhHvzSuxX8=,tag:F9MucLoRHvocoCZJfwIERg==,type:str]
+hoarder: ENC[AES256_GCM,data:q+UUERwmT5iKmXoDovbNjUDTz+KDQewrbAgY1IvsP/VA5DOJZEwXejVkrt9ROneCt6jBEqW4vrnTLKXrWCqD1VKPCIQLBIlvozB9jrXDTZH5wEUs1Zw3TG14xX6SYR2ouL3IlDpn6S3tdSqHa7OpCI0CUg69T7icD0kKMoMM52WpH5AvGU30mPXWIz4kMk3r3wOmhNEk8DN9zOdHiMHe7wH+JSH/aw==,iv:/4/0P/L5I9siLWrakP1I/a0rD+okELRHwlMvi8CcGgA=,tag:TMtCKNC7gfWbeIIy56BJGw==,type:str]
+immich: ENC[AES256_GCM,data:e+z2Jkx6Ntt/lxZVmSZRRMReMQ==,iv:rfykNZ0lp3TTogmF2XRmf6yo2MEqtoDqwMcntVDnEZo=,tag:1+wHR3WP+yWAVI7PSwV7Mw==,type:str]
 sops:
     kms: []
     gcp_kms: []
@@ -32,8 +34,8 @@ sops:
             YWNQcURKMSs2U0pOa3E0cTdCZ3RnalkKGayA7DBUQS+kn+6OYVBc6oTunF0qeZdt
             5b9DLHgh0HRWFm09XGSOog8K315d93Wzblw1My1/dXeEQX/ryinqUQ==
             -----END AGE ENCRYPTED FILE-----
-    lastmodified: "2025-02-16T11:01:33Z"
-    mac: ENC[AES256_GCM,data:/BYeH8Yn3vmnm3lFgHoQg8pv04RvqTtgPCEpOTppKBQU2n19baHdYhINUAavvzw5Z4fYDA+J1TvjXb3v1Q6CPjFSvDi74G7elPy408JkPx+Y9QQmxjnVKzrG3nMvqAkDTq23Bff1tWKBFb/UFq57ErdFipQ2FTdB+nnRGLvBpuY=,iv:olnKEKqiHzadzn+r6xWREytT9zI3sKxTGrsylggyAsU=,tag:azQU+Y/ftNpXVUT2smcxeQ==,type:str]
+    lastmodified: "2025-02-18T13:07:19Z"
+    mac: ENC[AES256_GCM,data:UsLsRi3/dgHfDAH6a3IvH1AT+9NKLJUDq5v87jU2mx39cxCnn+6iZC0ob/mkAJWObVCTrIMjTNdzarTc6U88qj6FKVBkxgva7ogAYj0/lkgBy9fGUfFZy5id1oENbK7g5iQ4HNYmhPUXESoMz11EKdNopmSeJ8eFMc8QyOip6MM=,iv:eju8Ifn5J+uhpnZkQJJNxtVa4uXgEvUV/em78utfnlk=,tag:ZMY/lJ2L4YNCl19OGfTFtA==,type:str]
     pgp: []
     unencrypted_suffix: _unencrypted
     version: 3.9.4