← Back to task

Commit 29cf56fd

commit 29cf56fdd2481bbb2be5b6c7b4855e7a82d47316
Author: Coder Agent <coder@agents.omni>
Date:   Thu Feb 19 16:16:37 2026

    Migrate beryllium from Tailscale Funnel to Headscale ingress
    
    Task-Id: t-437

diff --git a/Omni/Dev/Beryllium.nix b/Omni/Dev/Beryllium.nix
index a26d7250..163d3f6a 100755
--- a/Omni/Dev/Beryllium.nix
+++ b/Omni/Dev/Beryllium.nix
@@ -18,7 +18,6 @@ in
       ../Syncthing.nix
       ../Deploy/Deployer.nix
       ./Beryllium/Samba.nix
-      ./Beryllium/Caddy.nix
     ];
     networking.hostName = "beryllium";
     networking.domain = "beryl.bensima.com";
@@ -30,6 +29,6 @@ in
       enable = true;
       package = packages.deployer;
       manifestPackage = packages.deploy-manifest;
-      enableCaddy = false; # Ava uses Tailscale Funnel, not Caddy
+      enableCaddy = false; # beryllium ingress is managed by nginx in Omni/Dev/Vpn.nix
     };
   }
diff --git a/Omni/Dev/Beryllium/Ava.nix b/Omni/Dev/Beryllium/Ava.nix
index 0fe2b4cd..d370b8c8 100644
--- a/Omni/Dev/Beryllium/Ava.nix
+++ b/Omni/Dev/Beryllium/Ava.nix
@@ -51,9 +51,7 @@
     }
   ];
 
-  # Note: Tailscale Funnel for beryllium ingress is configured via:
-  #   tailscale funnel --bg 80
-  # Caddy then proxies all requests to Omni.Web on 8079.
-  # This persists in tailscaled config and doesn't need a systemd service.
-  # URL: https://beryllium.oryx-ide.ts.net/
+  # Public ingress is now served by nginx virtual hosts in Omni/Dev/Vpn.nix.
+  # Ava traffic is proxied to Omni.Web on port 8079.
+  # URL: https://ava.bensima.com/
 }
diff --git a/Omni/Dev/Vpn.nix b/Omni/Dev/Vpn.nix
index d064c1a2..353975a7 100644
--- a/Omni/Dev/Vpn.nix
+++ b/Omni/Dev/Vpn.nix
@@ -1,4 +1,4 @@
-{config, ...}:
+{config, lib, ...}:
 /*
 This module defines the VPN server using tailscale and a DNS-level filtering
 service with AdGuard. It's fairly restrictive, but blocks lots of malicious and
@@ -6,31 +6,74 @@ inappropriate sites, as well as a ton of ads.
 */
 let
   ports = import ../Cloud/Ports.nix;
+  isBeryllium = config.networking.hostName == "beryllium";
 in {
-  services.headscale = {
-    enable = false; # don't use headscale rn, just use tailscale.com
+  services.headscale = lib.mkIf isBeryllium {
+    enable = true;
     address = "0.0.0.0";
     port = ports.headscale;
-    settings = {dns.base_domain = "bensima.com";};
+    settings = {
+      server_url = "https://hs.bensima.com";
+      dns = {
+        base_domain = "hs.bensima.com";
+        magic_dns = true;
+        nameservers.global = ["100.64.0.1"];
+      };
+      derp = {
+        server.enabled = false;
+        urls = ["https://controlplane.tailscale.com/derpmap/default"];
+      };
+    };
   };
 
-  environment.systemPackages = [config.services.headscale.package];
+  environment.systemPackages = lib.optionals isBeryllium [config.services.headscale.package];
 
   services.tailscale = {
     enable = true;
-    extraUpFlags = [
-      "--accept-dns=true"
-      "--advertise-exit-node"
-    ];
+    extraUpFlags =
+      [
+        "--login-server=https://hs.bensima.com"
+        "--accept-dns=true"
+      ]
+      ++ lib.optionals isBeryllium ["--advertise-exit-node"];
   };
 
   networking.firewall = {
     checkReversePath = "loose";
     trustedInterfaces = ["tailscale0"];
     allowedUDPPorts = [config.services.tailscale.port];
+    allowedTCPPorts = lib.optionals isBeryllium [
+      ports.http
+      ports.https
+    ];
+  };
+
+  services.nginx = lib.mkIf isBeryllium {
+    enable = true;
+    recommendedProxySettings = true;
+    recommendedTlsSettings = true;
+    virtualHosts = {
+      "ava.bensima.com" = {
+        enableACME = true;
+        forceSSL = true;
+        locations."/" = {
+          proxyPass = "http://127.0.0.1:8079";
+          proxyWebsockets = true;
+        };
+      };
+
+      "hs.bensima.com" = {
+        enableACME = true;
+        forceSSL = true;
+        locations."/" = {
+          proxyPass = "http://127.0.0.1:${toString ports.headscale}";
+          proxyWebsockets = true;
+        };
+      };
+    };
   };
 
-  services.adguardhome = {
+  services.adguardhome = lib.mkIf isBeryllium {
     enable = true;
     openFirewall = true;
     settings = {