{ config, lib, pkgs, ... }: let inherit (lib) mkEnableOption mkIf mkOption ; cfg = config.my.services.monitoring; domain = config.networking.domain; hostname = config.networking.hostName; fqdn = "${hostname}.${domain}"; in { options.my.services.monitoring = let inherit (lib) types; in { enable = mkEnableOption "Enable monitoring"; domain = mkOption { type = types.str; default = "monitoring.${config.networking.domain}"; example = "monitoring.example.com"; description = "Domain to use in reverse proxy"; }; scrapeInterval = mkOption { type = types.str; default = "15s"; example = "1m"; description = "prometheus scrape interval"; }; }; config = mkIf cfg.enable { services.grafana = { enable = true; domain = cfg.domain; port = 3000; addr = "127.0.0.1"; provision = { enable = true; datasources = [ { name = "Prometheus"; type = "prometheus"; url = "http://localhost:${toString config.services.prometheus.port}"; jsonData = { timeInterval = cfg.scrapeInterval; }; } ]; dashboards = [ { name = "Node Exporter"; options.path = pkgs.packages.grafanaDashboards.node-exporter; disableDeletion = true; } { name = "NGINX"; options.path = pkgs.packages.grafanaDashboards.nginx; disableDeletion = true; } ]; }; }; services.prometheus = { enable = true; port = 9090; listenAddress = "127.0.0.1"; retentionTime = "2y"; exporters = { node = { enable = true; enabledCollectors = ["systemd"]; port = 9100; listenAddress = "127.0.0.1"; }; }; globalConfig = { scrape_interval = cfg.scrapeInterval; }; scrapeConfigs = [ { job_name = config.networking.hostName; static_configs = [ { targets = ["127.0.0.1:${toString config.services.prometheus.exporters.node.port}"]; } ]; } ]; }; services.nginx = { virtualHosts.${cfg.domain} = { locations."/" = { proxyPass = "http://127.0.0.1:${toString config.services.grafana.port}"; proxyWebsockets = true; }; forceSSL = true; useACMEHost = fqdn; }; }; security.acme.certs.${fqdn}.extraDomainNames = [cfg.domain]; }; }