Commit 979db4072d12

Vincent Demeester <vincent@sbr.pm>
2025-12-03 16:54:44
feat: Add homepage service and fix Syncthing redirect
- Deploy self-service homepage at home.sbr.pm with service directory - Fix Syncthing path redirect regex to properly append trailing slash - Pass globals to homepage package for dynamic service generation Signed-off-by: Vincent Demeester <vincent@sbr.pm>
1 parent 062eef5
Changed files (5)
overlays/default.nix
@@ -1,7 +1,15 @@
 { inputs, ... }:
+let
+  globals = import ../globals.nix { };
+in
 {
   # FIXME: migrate to pkgs and overlays on root
-  additions = final: _prev: import ../pkgs { pkgs = final; };
+  additions =
+    final: _prev:
+    import ../pkgs {
+      pkgs = final;
+      inherit globals;
+    };
   modifications = final: prev: {
     # example = prev.example.overrideAttrs (oldAttrs: rec {
     # ...
pkgs/homepage/default.nix
@@ -61,21 +61,18 @@ let
   ) globals.machines;
 
   # Generate syncthing service entries
-  syncthingServices =
-    [
-      {
-        name = "Syncthing (Overview)";
-        url = "https://syncthing.sbr.pm";
-        description = "File synchronization overview";
-      }
-    ]
-    ++ (lib.mapAttrsToList (
-      name: _machine: {
-        name = "Syncthing (${name})";
-        url = "https://syncthing.sbr.pm/${name}";
-        description = "Syncthing on ${name}";
-      }
-    ) syncthingMachines);
+  syncthingServices = [
+    {
+      name = "Syncthing (Overview)";
+      url = "https://syncthing.sbr.pm";
+      description = "File synchronization overview";
+    }
+  ]
+  ++ (lib.mapAttrsToList (name: _machine: {
+    name = "Syncthing (${name})";
+    url = "https://syncthing.sbr.pm/${name}";
+    description = "Syncthing on ${name}";
+  }) syncthingMachines);
 
   # Generate service entries from service list
   mkServiceEntry =
@@ -84,7 +81,8 @@ let
       # Capitalize first letter
       capitalize = str: (lib.toUpper (lib.substring 0 1 str)) + (lib.substring 1 (-1) str);
       displayName = capitalize serviceName;
-      description = category.descriptions.${serviceName} or "Service on ${globals.services.${serviceName}.host}";
+      description =
+        category.descriptions.${serviceName} or "Service on ${globals.services.${serviceName}.host}";
     in
     {
       name = displayName;
@@ -93,29 +91,24 @@ let
     };
 
   # Generate all service entries for a category
-  mkCategoryServices = category: map (serviceName: mkServiceEntry category serviceName) category.services;
+  mkCategoryServices =
+    category: map (serviceName: mkServiceEntry category serviceName) category.services;
 
   # Generate service list HTML
   mkServiceList =
     services:
-    lib.concatMapStringsSep "\n" (
-      service: ''
-        <div class="service-card">
-          <h3><a href="${service.url}">${service.name}</a></h3>
-          <p>${service.description}</p>
-        </div>
-      ''
-    ) services;
+    lib.concatMapStringsSep "\n" (service: ''
+      <div class="service-card">
+        <h3><a href="${service.url}">${service.name}</a></h3>
+        <p>${service.description}</p>
+      </div>
+    '') services;
 
   # Generate category section HTML
   mkCategorySection =
     categoryId: category:
     let
-      services =
-        if categoryId == "sync" then
-          syncthingServices
-        else
-          mkCategoryServices category;
+      services = if categoryId == "sync" then syncthingServices else mkCategoryServices category;
     in
     ''
       <section class="category">
@@ -236,11 +229,9 @@ let
 
         ${mkCategorySection "media" serviceCategories.media}
         ${mkCategorySection "downloads" serviceCategories.downloads}
-        ${
-          mkCategorySection "sync" {
-            title = "File Synchronization";
-          }
-        }
+        ${mkCategorySection "sync" {
+          title = "File Synchronization";
+        }}
         ${mkCategorySection "utilities" serviceCategories.utilities}
       </div>
     </body>
pkgs/default.nix
@@ -3,6 +3,7 @@
 
 {
   pkgs ? (import ../nixpkgs.nix) { },
+  globals ? { },
 }:
 let
   compileEmacsFiles = pkgs.callPackage ./emacs/builder.nix;
@@ -22,6 +23,7 @@ in
   gh-restart-failed = pkgs.callPackage ../tools/gh-restart-failed { };
   arr = pkgs.callPackage ../tools/arr { };
   download-kiwix-zim = pkgs.callPackage ../tools/download-kiwix-zim { };
+  homepage = pkgs.callPackage ./homepage { inherit globals; };
 
   chmouzies-ai = pkgs.callPackage ./chmouzies/ai.nix { };
   chmouzies-git = pkgs.callPackage ./chmouzies/git.nix { };
systems/athena/extra.nix
@@ -58,6 +58,20 @@
           '';
         };
       };
+      virtualHosts."home.athena.sbr.pm" = {
+        listen = [
+          {
+            addr = "0.0.0.0";
+            port = 8080;
+          }
+        ];
+        locations."/" = {
+          root = "${pkgs.homepage}";
+          extraConfig = ''
+            index index.html;
+          '';
+        };
+      };
     };
   };
 }
systems/rhea/extra.nix
@@ -192,7 +192,7 @@
             lib.nameValuePair "syncthing-${name}-addslash" {
               redirectRegex = {
                 regex = "^(https?://[^/]+/${name})$";
-                replacement = "$${1}/";
+                replacement = "$$1/";
                 permanent = true;
               };
             }
@@ -206,6 +206,7 @@
               // {
                 # Override immich router to add large file upload middleware
                 immich = mkRouterWithMiddlewares "immich" [ "immich.sbr.pm" ] [ "immich-buffering" ];
+                home = mkRouter "home" [ "home.sbr.pm" ];
                 kiwix = mkRouter "kiwix" [ "kiwix.sbr.pm" ];
                 n8n = mkRouter "n8n" [ "n8n.sbr.pm" ];
                 paperless = mkRouter "paperless" [ "paperless.sbr.pm" ];
@@ -215,6 +216,7 @@
               syncthingServices
               // localHttpServices
               // {
+                home = mkService "http://${builtins.head globals.machines.athena.net.ips}:8080";
                 kiwix = mkService "http://${builtins.head globals.machines.sakhalin.net.ips}:8080";
                 n8n = mkService "http://${builtins.head globals.machines.sakhalin.net.ips}:5678";
                 paperless = mkService "http://${builtins.head globals.machines.sakhalin.net.ips}:8000";