From a0c3e70c663c47f3745348c2fc43360fb0a35609 Mon Sep 17 00:00:00 2001 From: cnst Date: Fri, 18 Jul 2025 00:51:33 +0200 Subject: [PATCH] add homepage --- hosts/sobotka/server.nix | 3 + modules/default.nix | 3 +- modules/server/homepage/default.nix | 192 ++++++++++++++++++++++++++++ 3 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 modules/server/homepage/default.nix diff --git a/hosts/sobotka/server.nix b/hosts/sobotka/server.nix index 7daf045e..967d85f0 100644 --- a/hosts/sobotka/server.nix +++ b/hosts/sobotka/server.nix @@ -10,6 +10,9 @@ apiKeyFile = config.age.secrets.cloudflareFirewallApiKey.path; zoneId = "0027acdfb8bbe010f55b676ad8698dfb"; }; + homepage = { + enable = true; + }; vaultwarden = { enable = true; url = "vault.cnst.dev"; diff --git a/modules/default.nix b/modules/default.nix index 9f7e6cdd..4700f771 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -69,7 +69,7 @@ ./nixos/programs/blender ./nixos/programs/corectrl ./nixos/programs/fish - ./nixos/programs/gamemode + ./nixos/programs/gamemodeservices ./nixos/programs/gamescope ./nixos/programs/gimp ./nixos/programs/gnome @@ -122,6 +122,7 @@ ./server ./server/caddy ./server/fail2ban + ./server/homepage ./server/vaultwarden ]; }; diff --git a/modules/server/homepage/default.nix b/modules/server/homepage/default.nix new file mode 100644 index 00000000..680be0e5 --- /dev/null +++ b/modules/server/homepage/default.nix @@ -0,0 +1,192 @@ +{ + config, + lib, + ... +}: let + service = "homepage-dashboard"; + cfg = config.server.homepage; + server = config.server; +in { + options.server.homepage = { + enable = lib.mkEnableOption { + description = "Enable ${service}"; + }; + misc = lib.mkOption { + default = []; + type = lib.types.listOf ( + lib.types.attrsOf ( + lib.types.submodule { + options = { + description = lib.mkOption { + type = lib.types.str; + }; + href = lib.mkOption { + type = lib.types.str; + }; + siteMonitor = lib.mkOption { + type = lib.types.str; + }; + icon = lib.mkOption { + type = lib.types.str; + }; + }; + } + ) + ); + }; + }; + config = lib.mkIf cfg.enable { + services.glances.enable = true; + services.${service} = { + enable = true; + environmentFile = builtins.toFile "homepage.env" "HOMEPAGE_ALLOWED_HOSTS=${server.domain}"; + customCSS = '' + body, html { + font-family: SF Pro Display, Helvetica, Arial, sans-serif !important; + } + .font-medium { + font-weight: 700 !important; + } + .font-light { + font-weight: 500 !important; + } + .font-thin { + font-weight: 400 !important; + } + #information-widgets { + padding-left: 1.5rem; + padding-right: 1.5rem; + } + div#footer { + display: none; + } + .services-group.basis-full.flex-1.px-1.-my-1 { + padding-bottom: 3rem; + }; + ''; + settings = { + layout = [ + { + Glances = { + header = false; + style = "row"; + columns = 4; + }; + } + { + Arr = { + header = true; + style = "column"; + }; + } + { + Downloads = { + header = true; + style = "column"; + }; + } + { + Media = { + header = true; + style = "column"; + }; + } + { + Services = { + header = true; + style = "column"; + }; + } + ]; + headerStyle = "clean"; + statusStyle = "dot"; + hideVersion = "true"; + }; + services = let + homepageCategories = [ + "Arr" + "Media" + "Downloads" + "Services" + "Smart Home" + ]; + hl = config.homelab.services; + homepageServices = x: (lib.attrsets.filterAttrs ( + name: value: value ? homepage && value.homepage.category == x + ) + server); + in + lib.lists.forEach homepageCategories (cat: { + "${cat}" = + lib.lists.forEach (lib.attrsets.mapAttrsToList (name: value: name) (homepageServices "${cat}")) + (x: { + "${hl.${x}.homepage.name}" = { + icon = hl.${x}.homepage.icon; + description = hl.${x}.homepage.description; + href = "https://${hl.${x}.url}"; + siteMonitor = "https://${hl.${x}.url}"; + }; + }); + }) + ++ [{Misc = cfg.misc;}] + ++ [ + { + Glances = let + port = toString config.services.glances.port; + in [ + { + Info = { + widget = { + type = "glances"; + url = "http://localhost:${port}"; + metric = "info"; + chart = false; + version = 4; + }; + }; + } + { + "CPU Temp" = { + widget = { + type = "glances"; + url = "http://localhost:${port}"; + metric = "sensor:Package id 0"; + chart = false; + version = 4; + }; + }; + } + { + Processes = { + widget = { + type = "glances"; + url = "http://localhost:${port}"; + metric = "process"; + chart = false; + version = 4; + }; + }; + } + { + Network = { + widget = { + type = "glances"; + url = "http://localhost:${port}"; + metric = "network:enp6s0"; + chart = false; + version = 4; + }; + }; + } + ]; + } + ]; + }; + services.caddy.virtualHosts."${server.domain}" = { + useACMEHost = server.domain; + extraConfig = '' + reverse_proxy http://127.0.0.1:${toString config.services.${service}.listenPort} + ''; + }; + }; +}