diff --git a/hosts/jupiter/configuration.nix b/hosts/jupiter/configuration.nix index ba947f7..98c1861 100644 --- a/hosts/jupiter/configuration.nix +++ b/hosts/jupiter/configuration.nix @@ -14,6 +14,7 @@ ../../services/network/caddy.nix ../../services/vpn/tailscale.nix ../../services/monitoring/node-exporter.nix + ../../services/monitoring/victoriametrics.nix ../../services/media/jellyfin.nix ../../services/media/sabnzbd.nix ../../services/media/prowlarr.nix diff --git a/services/monitoring/victoriametrics.nix b/services/monitoring/victoriametrics.nix new file mode 100644 index 0000000..e6c6aeb --- /dev/null +++ b/services/monitoring/victoriametrics.nix @@ -0,0 +1,79 @@ +{ ... }: + +# VictoriaMetrics single-node store for the homelab dashboard on Jupiter. It +# listens on all interfaces, but tailscale.nix makes tailscale0 the only trusted ingress; +# the host firewall therefore keeps :8428 off the LAN and public interfaces. +# +# The scrape targets are the node_exporter instances enabled by +# services/monitoring/node-exporter.nix on every real host. MagicDNS names use +# the tailnet's orbit.sol suffix (see services/vpn/headscale.nix). +{ + services.victoriametrics = { + enable = true; + retentionPeriod = "15d"; + listenAddress = ":8428"; + + prometheusConfig = { + global.scrape_interval = "5s"; + + scrape_configs = [ + { + job_name = "node-exporter"; + static_configs = [ + { + targets = [ "127.0.0.1:9100" ]; + labels.host = "jupiter"; + } + { + targets = [ "mars.orbit.sol:9100" ]; + labels.host = "mars"; + } + { + targets = [ "neptun.orbit.sol:9100" ]; + labels.host = "neptun"; + } + { + targets = [ "terra.orbit.sol:9100" ]; + labels.host = "terra"; + } + ]; + } + { + job_name = "node-exporter-mercury"; + scrape_interval = "15s"; + scrape_timeout = "10s"; + static_configs = [ + { + targets = [ "mercury.orbit.sol:9100" ]; + labels.host = "mercury"; + } + ]; + } + { + job_name = "victoriametrics"; + static_configs = [ + { + targets = [ "127.0.0.1:8428" ]; + labels.host = "jupiter"; + } + ]; + } + ]; + }; + }; + + # Start after Tailscale has had a chance to establish MagicDNS. This is only + # ordering, not a hard dependency: VictoriaMetrics still starts locally if + # another host or the tailnet is temporarily unavailable. + systemd.services.victoriametrics.after = [ "tailscaled-autoconnect.service" ]; + + fileSystems."/var/lib/private/victoriametrics" = { + device = "/mnt/data/AppData/victoriametrics"; + fsType = "none"; + options = [ "bind" "nofail" ]; + }; + + # The service path is under /var/lib/private, so systemd would otherwise + # derive its mount dependency from the eMMC-backed path alone. + systemd.services.victoriametrics.unitConfig.RequiresMountsFor = [ "/mnt/data" ]; +}