# Homepage dashboard (gethomepage.dev) configuration for homeserver-1 # # This file holds the full dashboard definition (settings, services, widgets). # It is imported by configuration.nix. Edit this file to change what the # dashboard shows, then run: # nixos-rebuild switch --target-host petere@homeserver-1 --flake .#homeserver-1 --use-remote-sudo { config , lib , ... }: let # Build a Tailscale widget tile for the Tailnet tab. Shared so the # highlight rules (expiry / last-seen) are defined once. # Returns a service entry: { "" = { icon; href; description; widget; } } tailscaleTile = name: deviceid: description: { ${name} = { icon = "sh-tailscale"; href = "https://login.tailscale.com/admin/machines"; inherit description; widget = { type = "tailscale"; inherit deviceid; key = "{{HOMEPAGE_VAR_TAILSCALE_API_KEY}}"; # Highlight rules match the rendered field values (e.g. "24w", "Never", # "8h Ago", "2w Ago"). Warn = expiring within a week, danger = offline >24h. highlight = { expires = { string = [ { level = "warn"; when = "regex"; # 1-7 days, or hours/minutes/seconds remaining (i.e. within a week) value = "^\\d+[dhms]$"; } ]; }; last_seen = { string = [ { level = "danger"; when = "regex"; # days/weeks/years ago (i.e. not seen for more than 24 hours) value = "^\\d+[dwy] Ago$"; } ]; }; }; }; }; }; in { services.homepage = { enable = true; port = 8082; allowedHosts = [ "localhost" "127.0.0.1" "homeserver-1" "homeserver-1.gerbil-opah.ts.net" ]; openFirewall = false; # Exposed on Tailscale only (see firewall in configuration.nix) # API keys / secrets for service widgets (HOMEPAGE_VAR_* vars) environmentFiles = [ config.sops.secrets."homeserver-1/homepage-env".path ]; settings = { title = "HomeServer"; language = "en"; theme = "dark"; color = "slate"; statusStyle = "dot"; # Tabs: each layout group's `tab` value controls which tab it appears on. # Groups without a `tab` (or with no layout entry) show on every tab. layout = { # ---- Monitoring tab ---- "Homeserver-1 Monitoring" = { tab = "Monitoring"; style = "row"; columns = 1; "HS1 System" = { style = "row"; columns = 2; }; "HS1 Disks" = { style = "row"; columns = 2; # NVMe + SDA side by side }; }; "MCF Server Monitoring" = { tab = "Monitoring"; style = "row"; columns = 1; "MCF System" = { style = "row"; columns = 2; }; "MCF Disks" = { style = "row"; columns = 2; # SDB (system) + SDA (data) side by side }; }; "Richmond Server Monitoring" = { tab = "Monitoring"; style = "row"; columns = 1; "Richmond System" = { style = "row"; columns = 2; }; "Richmond Disks" = { style = "row"; columns = 2; # SDB (system) + SDA (data) side by side }; }; # ---- Homeserver-1 tab ---- Media = { tab = "Homeserver-1"; style = "row"; columns = 2; }; System = { tab = "Homeserver-1"; style = "row"; columns = 3; }; # ---- MCF Server tab (populate with future mcf-server services) ---- # "MCF Server Apps" = { # tab = "MCF Server"; # style = "row"; # columns = 4; # }; # ---- Richmond Server tab ---- "Richmond Server Apps" = { tab = "Richmond Server"; style = "row"; columns = 3; }; # ---- Tailnet tab (one Tailscale widget per machine) ---- Tailnet = { tab = "Tailnet"; style = "row"; columns = 3; }; }; }; services = [ { "Homeserver-1 Monitoring" = [ { "HS1 System" = [ { "System" = { widget = { type = "glances"; url = "http://127.0.0.1:61208"; version = 4; # Glances v4.x metric = "info"; }; }; } { "CPU" = { widget = { type = "glances"; url = "http://127.0.0.1:61208"; version = 4; metric = "cpu"; }; }; } { "Memory" = { widget = { type = "glances"; url = "http://127.0.0.1:61208"; version = 4; metric = "memory"; }; }; } { "Processes" = { widget = { type = "glances"; url = "http://127.0.0.1:61208"; version = 4; metric = "process"; }; }; } ]; } { "HS1 Disks" = [ { "NVMe - System" = { widget = { type = "glances"; url = "http://127.0.0.1:61208"; version = 4; metric = "disk:nvme0n1"; }; }; } { "SDA - Data" = { widget = { type = "glances"; url = "http://127.0.0.1:61208"; version = 4; metric = "disk:sda"; }; }; } ]; } ]; } { "MCF Server Monitoring" = [ { "MCF System" = [ { "System" = { widget = { type = "glances"; url = "http://mcf-server.gerbil-opah.ts.net:61208"; version = 4; # Glances v4.x metric = "info"; }; }; } { "CPU" = { widget = { type = "glances"; url = "http://mcf-server.gerbil-opah.ts.net:61208"; version = 4; metric = "cpu"; }; }; } { "Memory" = { widget = { type = "glances"; url = "http://mcf-server.gerbil-opah.ts.net:61208"; version = 4; metric = "memory"; }; }; } { "Processes" = { widget = { type = "glances"; url = "http://mcf-server.gerbil-opah.ts.net:61208"; version = 4; metric = "process"; }; }; } ]; } { "MCF Disks" = [ { "SDB - System" = { widget = { type = "glances"; url = "http://mcf-server.gerbil-opah.ts.net:61208"; version = 4; metric = "disk:sdb"; }; }; } { "SDA - Data" = { widget = { type = "glances"; url = "http://mcf-server.gerbil-opah.ts.net:61208"; version = 4; metric = "disk:sda"; }; }; } ]; } ]; } { "Richmond Server Monitoring" = [ { "Richmond System" = [ { "System" = { widget = { type = "glances"; url = "http://richmond-server.gerbil-opah.ts.net:61208"; version = 4; # Glances v4.x metric = "info"; }; }; } { "CPU" = { widget = { type = "glances"; url = "http://richmond-server.gerbil-opah.ts.net:61208"; version = 4; metric = "cpu"; }; }; } { "Memory" = { widget = { type = "glances"; url = "http://richmond-server.gerbil-opah.ts.net:61208"; version = 4; metric = "memory"; }; }; } { "Processes" = { widget = { type = "glances"; url = "http://richmond-server.gerbil-opah.ts.net:61208"; version = 4; metric = "process"; }; }; } ]; } { "Richmond Disks" = [ { "SDB - System" = { widget = { type = "glances"; url = "http://richmond-server.gerbil-opah.ts.net:61208"; version = 4; metric = "disk:sdb"; }; }; } { "SDA - Data" = { widget = { type = "glances"; url = "http://richmond-server.gerbil-opah.ts.net:61208"; version = 4; metric = "disk:sda"; }; }; } ]; } ]; } { Media = [ { Jellyfin = { icon = "sh-jellyfin"; href = "http://jellyfin.edley.me"; description = "Movies & TV"; siteMonitor = "http://127.0.0.1:8096"; widget = { type = "jellyfin"; url = "http://127.0.0.1:8096"; key = "{{HOMEPAGE_VAR_JELLYFIN_API_KEY}}"; enableBlocks = true; enableNowPlaying = true; }; }; } { Immich = { icon = "sh-immich"; href = "http://immich.edley.me"; description = "Photo & Video"; siteMonitor = "http://127.0.0.1:2283"; widget = { type = "immich"; url = "http://127.0.0.1:2283"; key = "{{HOMEPAGE_VAR_IMMICH_API_KEY}}"; version = 2; # Immich >= 1.118 }; }; } ]; } { System = [ { Backrest = { icon = "sh-backrest"; href = "http://homeserver-1.gerbil-opah.ts.net:9898"; description = "Restic backup UI"; siteMonitor = "http://127.0.0.1:9898"; widget = { type = "backrest"; url = "http://127.0.0.1:9898"; }; }; } { "Pocket ID" = { icon = "sh-pocketbase"; href = "https://homeserver-1.gerbil-opah.ts.net:8443"; description = "SSO / Identity"; }; } { Gitea = { icon = "sh-gitea"; href = "https://gitea.edley.me"; description = "Git hosting"; siteMonitor = "http://127.0.0.1:3000"; }; } ]; } # ---- MCF Server tab: add future mcf-server services here ---- # { # "MCF Server Apps" = [ # { # "MyApp" = { # icon = "sh-myservice"; # href = "http://mcf-server.gerbil-opah.ts.net:"; # siteMonitor = "http://mcf-server.gerbil-opah.ts.net:"; # }; # } # ]; # } { "Richmond Server Apps" = [ { PiHole = { icon = "sh-pihole"; href = "http://richmond-server.gerbil-opah.ts.net/admin"; description = "Network-wide ad blocking"; siteMonitor = "http://richmond-server.gerbil-opah.ts.net"; widget = { type = "pihole"; url = "http://richmond-server.gerbil-opah.ts.net"; version = 6; # Pi-hole v6 key = "{{HOMEPAGE_VAR_PIHOLE_API_KEY}}"; }; }; } { Castopod = { icon = "sh-castopod"; href = "http://richmond-server.gerbil-opah.ts.net:8080"; description = "Podcasting platform"; siteMonitor = "http://richmond-server.gerbil-opah.ts.net:8080"; }; } { Ntfy = { icon = "sh-ntfy"; href = "https://ntfy.edley.me"; description = "Push notifications"; siteMonitor = "http://richmond-server.gerbil-opah.ts.net:8085"; }; } ]; } # ---- Tailnet tab: one Tailscale widget per machine ---- { Tailnet = [ (tailscaleTile "Homeserver-1" "7629334038136604" "homeserver-1.gerbil-opah.ts.net") (tailscaleTile "MCF Server" "6531912398509392" "mcf-server.gerbil-opah.ts.net") (tailscaleTile "Richmond Server" "4591058654038528" "richmond-server.gerbil-opah.ts.net") (tailscaleTile "x1carbon" "3486385364789872" "x1carbon.gerbil-opah.ts.net") (tailscaleTile "x470" "210979648507396" "x470.gerbil-opah.ts.net") (tailscaleTile "caitlin-x1" "4406025993575891" "caitlin-x1.gerbil-opah.ts.net") (tailscaleTile "Mary Laptop" "5830538092696610" "mary-laptop.gerbil-opah.ts.net") (tailscaleTile "Pluto" "4170550062707667" "pluto.gerbil-opah.ts.net") (tailscaleTile "TheBorg" "2268885677960290" "theborg.gerbil-opah.ts.net") (tailscaleTile "Server" "3605859775136634" "server.gerbil-opah.ts.net") (tailscaleTile "Homeserver" "5665047953117744" "homeserver.gerbil-opah.ts.net") (tailscaleTile "MCF Projector" "5131578183597553" "mcf-projector.gerbil-opah.ts.net") (tailscaleTile "MCF Stream" "6804850380243723" "mcf-stream.gerbil-opah.ts.net") (tailscaleTile "Yoga 12" "1716848030756573" "yoga12.gerbil-opah.ts.net") (tailscaleTile "Pixel 9 Pro XL" "6766405315162342" "pixel-9-pro-xl.gerbil-opah.ts.net") ]; } ]; widgets = [ { resources = { cpu = true; memory = true; disk = "/"; }; } { search = { provider = "duckduckgo"; target = "_blank"; }; } { datetime = { text_size = "xl"; locale = "en-GB"; # UK date format (dd/mm/yy) format = { dateStyle = "short"; timeStyle = "short"; }; }; } ]; }; }