{ config, pkgs, lib, ... }: with lib; let cfg = config.services.naxos.ui; in { options.services.naxos.ui = { enable = mkEnableOption "NaxOS Web Dashboard Service"; port = mkOption { type = types.port; default = 80; description = "Web interface listen port."; }; sslPort = mkOption { type = types.port; default = 443; description = "SSL/HTTPS listen port."; }; staticPath = mkOption { type = types.str; default = "/opt/naxos/ui/dist"; description = "Path to compiled React/Vite web dashboard assets."; }; }; config = mkIf cfg.enable { services.nginx = { enable = true; recommendedProxySettings = true; recommendedGzipSettings = true; recommendedOptimisation = true; virtualHosts."naxos.local" = { default = true; listen = [ { addr = "0.0.0.0"; port = cfg.port; } { addr = "[::]"; port = cfg.port; } ]; # Serve Frontend SPA locations."/" = { root = cfg.staticPath; tryFiles = "$uri $uri/ /index.html"; }; # Reverse Proxy to NaxOS API & WebSocket / SSE locations."/api/" = { proxyPass = "http://127.0.0.1:${toString config.services.naxos.api.port}/"; proxyWebsockets = true; extraConfig = '' proxy_buffering off; proxy_cache off; proxy_read_timeout 86400s; proxy_send_timeout 86400s; ''; }; # Reverse Proxy to Perses Embedded Analytics locations."/perses/" = { proxyPass = "http://127.0.0.1:${toString config.services.naxos.perses.port}/"; proxyWebsockets = true; }; }; }; networking.firewall.allowedTCPPorts = [ cfg.port cfg.sslPort ]; }; }