diff --git a/.rules b/.rules index aba24577..38ea90ae 100644 --- a/.rules +++ b/.rules @@ -2,10 +2,8 @@ You are a sysadmin that manages server configurations and deployments in nixos/nix-darwin and the nix language. # Instructions -1. Do not create new markdown files in this repository. -2. Do not add any helper scripts or shell scripts. -3. Do not add any example / snippets or sample code. +1. DO NOT under any circumstance create any new markdown files in this repository. +2. DO NOT add any helper scripts or shell scripts. +3. DO NOT add any example / snippets or sample code. 4. All configurations must be done using nix expressions if possible. 5. When adding any new file ensure it follows the existing naming conventions and directory structure. - - diff --git a/home/services/gtk.nix b/home/services/gtk.nix index bc482fce..d2a715ea 100644 --- a/home/services/gtk.nix +++ b/home/services/gtk.nix @@ -4,18 +4,19 @@ device, ... }: { + stylix.targets.gtk.enable = false; gtk = { enable = device.is "ryu"; - # theme = { - # name = "catppuccin-mocha-mauve-standard+normal"; - # package = pkgs.catppuccinThemes.gtk; - # # package = pkgs.catppuccin-gtk.override { - # # variant = "mocha"; - # # size = "standard"; - # # accents = ["mauve"]; - # # tweaks = ["normal"]; - # # }; - # }; + theme = { + name = "catppuccin-mocha-mauve-standard+normal"; + package = pkgs.catppuccinThemes.gtk; + # package = pkgs.catppuccin-gtk.override { + # variant = "mocha"; + # size = "standard"; + # accents = ["mauve"]; + # tweaks = ["normal"]; + # }; + }; iconTheme = { name = "Papirus-Dark"; diff --git a/nixos/mirai/services/default.nix b/nixos/mirai/services/default.nix index 9a92edfc..e9628cee 100644 --- a/nixos/mirai/services/default.nix +++ b/nixos/mirai/services/default.nix @@ -8,9 +8,10 @@ ./flaresolverr.nix ./gitea.nix ./homepage.nix - ./immich.nix + # ./immich.nix ./llama.nix ./lldap.nix + ./monitoring.nix ./nextcloud.nix ./prowlarr.nix ./resolved.nix diff --git a/nixos/mirai/services/monitoring.nix b/nixos/mirai/services/monitoring.nix new file mode 100644 index 00000000..990ab7b5 --- /dev/null +++ b/nixos/mirai/services/monitoring.nix @@ -0,0 +1,273 @@ +{ + config, + pkgs, + ... +}: { + sops.secrets = { + "grafana/adminPassword" = { + owner = "grafana"; + group = "grafana"; + }; + oauth-client-secret-grafana-authelia = { + owner = config.systemd.services.authelia-darksailor.serviceConfig.User; + key = "authelia/oidc/grafana/client_secret"; + restartUnits = [ + "authelia-darksailor.service" + ]; + }; + oauth-client-secret-grafana = { + owner = config.systemd.services.grafana.serviceConfig.User; + key = "authelia/oidc/grafana/client_secret"; + restartUnits = [ + "grafana" + ]; + }; + }; + services = { + prometheus = { + enable = true; + port = 9090; + listenAddress = "0.0.0.0"; + + scrapeConfigs = [ + { + job_name = "tsuba-node"; + static_configs = [ + { + targets = ["tsuba:9100"]; + } + ]; + scrape_interval = "15s"; + scrape_timeout = "10s"; + } + { + job_name = "tsuba-process"; + static_configs = [ + { + targets = ["tsuba:9256"]; + } + ]; + scrape_interval = "15s"; + scrape_timeout = "10s"; + } + { + job_name = "ryu-node"; + static_configs = [ + { + targets = ["ryu:9100"]; + } + ]; + scrape_interval = "15s"; + scrape_timeout = "10s"; + } + { + job_name = "ryu-process"; + static_configs = [ + { + targets = ["ryu:9256"]; + } + ]; + scrape_interval = "15s"; + scrape_timeout = "10s"; + } + { + job_name = "mirai-node"; + static_configs = [ + { + targets = ["localhost:9100"]; + } + ]; + scrape_interval = "15s"; + scrape_timeout = "10s"; + } + { + job_name = "mirai-process"; + static_configs = [ + { + targets = ["localhost:9256"]; + } + ]; + scrape_interval = "15s"; + scrape_timeout = "10s"; + } + ]; + + retentionTime = "30d"; + + globalConfig = { + scrape_interval = "15s"; + evaluation_interval = "15s"; + }; + }; + + prometheus.exporters = { + node = { + enable = true; + enabledCollectors = [ + "systemd" + "textfile" + "filesystem" + "loadavg" + "meminfo" + "netdev" + "stat" + "time" + "uname" + "vmstat" + ]; + port = 9100; + }; + process = { + enable = true; + settings.process_names = [ + { + name = "{{.Comm}}"; + cmdline = [".*"]; + } + ]; + }; + }; + + grafana = { + enable = true; + settings = { + server = { + http_addr = "0.0.0.0"; + http_port = 3333; + domain = "monitoring.darksailor.dev"; + root_url = "https://monitoring.darksailor.dev"; + }; + security = { + admin_user = "admin"; + admin_password = "$__file{${config.sops.secrets."grafana/adminPassword".path}}"; + }; + auth = { + disable_login_form = true; + }; + "auth.basic" = { + enabled = false; + }; + "auth.generic_oauth" = { + enabled = true; + name = "Authelia"; + client_id = "grafana"; + client_secret = "$__file{${config.sops.secrets.oauth-client-secret-grafana.path}}"; + scopes = "openid profile email groups"; + auth_url = "https://auth.darksailor.dev/api/oidc/authorization"; + token_url = "https://auth.darksailor.dev/api/oidc/token"; + api_url = "https://auth.darksailor.dev/api/oidc/userinfo"; + login_attribute_path = "preferred_username"; + groups_attribute_path = "groups"; + name_attribute_path = "name"; + use_pkce = true; + auto_login = true; + allow_sign_up = true; + # use_refresh_token = true; + # id_token_attribute_name = "id_token"; + # role_attribute_path = "groups"; + }; + }; + + provision = { + enable = true; + datasources.settings.datasources = [ + { + name = "Prometheus"; + type = "prometheus"; + access = "proxy"; + url = "http://localhost:9090"; + isDefault = true; + jsonData = { + timeInterval = "15s"; + }; + } + ]; + + dashboards.settings = { + apiVersion = 1; + providers = [ + { + name = "default"; + type = "file"; + options.path = "/var/lib/grafana/dashboards"; + } + ]; + }; + }; + }; + + caddy.virtualHosts."monitoring.darksailor.dev".extraConfig = '' + reverse_proxy localhost:${builtins.toString config.services.grafana.settings.server.http_port} + ''; + + authelia = { + instances.darksailor = { + settings = { + identity_providers = { + oidc = { + claims_policies = { + grafana = { + id_token = [ + "email" + "name" + "groups" + "preferred_username" + ]; + }; + }; + clients = [ + { + client_name = "Grafana"; + client_id = "grafana"; + claims_policy = "grafana"; + client_secret = ''{{ secret "${config.sops.secrets.oauth-client-secret-grafana-authelia.path}" }}''; + public = false; + authorization_policy = "one_factor"; + require_pkce = true; + pkce_challenge_method = "S256"; + redirect_uris = [ + "https://monitoring.darksailor.dev/login/generic_oauth" + ]; + scopes = [ + "openid" + "profile" + "email" + "groups" + ]; + response_types = ["code"]; + grant_types = ["authorization_code"]; + userinfo_signed_response_alg = "none"; + access_token_signed_response_alg = "none"; + token_endpoint_auth_method = "client_secret_basic"; + } + ]; + }; + }; + }; + }; + }; + }; + + # SOPS secrets for Grafana + + # Create dashboard directory and copy dashboards + systemd.tmpfiles.rules = [ + "d /var/lib/grafana/dashboards 0755 grafana grafana" + ]; + + # Open firewall ports + networking.firewall = { + allowedTCPPorts = [ + 3000 # Grafana + 9090 # Prometheus + 9100 # Node exporter + 9256 # Process exporter + ]; + # Allow Tailscale traffic for metrics scraping + trustedInterfaces = ["tailscale0"]; + }; + + # Ensure Grafana service starts after PostgreSQL + # systemd.services.grafana.after = ["postgresql.service"]; + # systemd.services.grafana.requires = ["postgresql.service"]; +}