diff --git a/nixos/doc/manual/release-notes/rl-2411.section.md b/nixos/doc/manual/release-notes/rl-2411.section.md index 32c3dc2f5428..ed1b20e62d0e 100644 --- a/nixos/doc/manual/release-notes/rl-2411.section.md +++ b/nixos/doc/manual/release-notes/rl-2411.section.md @@ -113,6 +113,8 @@ - [Localsend](https://localsend.org/), an open source cross-platform alternative to AirDrop. Available as [programs.localsend](#opt-programs.localsend.enable). +- [Gatus](https://github.com/TwiN/gatus), an automated developer-oriented status page. Available as [services.gatus](#opt-services.gatus.enable). + - [cryptpad](https://cryptpad.org/), a privacy-oriented collaborative platform (docs/drive/etc), has been added back. Available as [services.cryptpad](#opt-services.cryptpad.enable). - [realm](https://github.com/zhboner/realm), a simple, high performance relay server written in rust. Available as [services.realm.enable](#opt-services.realm.enable). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 5068a04c8d34..cb272330a692 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -882,6 +882,7 @@ ./services/monitoring/datadog-agent.nix ./services/monitoring/do-agent.nix ./services/monitoring/fusion-inventory.nix + ./services/monitoring/gatus.nix ./services/monitoring/goss.nix ./services/monitoring/grafana-agent.nix ./services/monitoring/grafana-image-renderer.nix diff --git a/nixos/modules/services/monitoring/gatus.nix b/nixos/modules/services/monitoring/gatus.nix new file mode 100644 index 000000000000..408115f5d514 --- /dev/null +++ b/nixos/modules/services/monitoring/gatus.nix @@ -0,0 +1,132 @@ +{ + pkgs, + lib, + config, + ... +}: +let + cfg = config.services.gatus; + + settingsFormat = pkgs.formats.yaml { }; + + inherit (lib) + getExe + literalExpression + maintainers + mkEnableOption + mkIf + mkOption + mkPackageOption + ; + + inherit (lib.types) + bool + int + nullOr + path + submodule + ; +in +{ + options.services.gatus = { + enable = mkEnableOption "Gatus"; + + package = mkPackageOption pkgs "gatus" { }; + + configFile = mkOption { + type = path; + default = settingsFormat.generate "gatus.yaml" cfg.settings; + defaultText = literalExpression '' + let settingsFormat = pkgs.formats.yaml { }; in settingsFormat.generate "gatus.yaml" cfg.settings; + ''; + description = '' + Path to the Gatus configuration file. + Overrides any configuration made using the `settings` option. + ''; + }; + + environmentFile = mkOption { + type = nullOr path; + default = null; + description = '' + File to load as environment file. + Environmental variables from this file can be interpolated in the configuration file using `''${VARIABLE}`. + This is useful to avoid putting secrets into the nix store. + ''; + }; + + settings = mkOption { + type = submodule { + freeformType = settingsFormat.type; + options = { + web.port = mkOption { + type = int; + default = 8080; + description = '' + The TCP port to serve the Gatus service at. + ''; + }; + }; + }; + + default = { }; + + example = literalExpression '' + { + web.port = 8080; + endpoints = [{ + name = "website"; + url = "https://twin.sh/health"; + interval = "5m"; + conditions = [ + "[STATUS] == 200" + "[BODY].status == UP" + "[RESPONSE_TIME] < 300" + ]; + }]; + } + ''; + + description = '' + Configuration for Gatus. + Supported options can be found at the [docs](https://gatus.io/docs). + ''; + }; + + openFirewall = mkOption { + type = bool; + default = false; + description = '' + Whether to open the firewall for the Gatus web interface. + ''; + }; + }; + + config = mkIf cfg.enable { + systemd.services.gatus = { + description = "Automated developer-oriented status page"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + DynamicUser = true; + User = "gatus"; + Group = "gatus"; + Type = "simple"; + Restart = "on-failure"; + ExecStart = getExe cfg.package; + StateDirectory = "gatus"; + SyslogIdentifier = "gatus"; + EnvironmentFile = lib.optional (cfg.environmentFile != null) cfg.environmentFile; + }; + + environment = { + GATUS_CONFIG_PATH = cfg.configFile; + }; + }; + + networking.firewall.allowedTCPPorts = lib.optionals cfg.openFirewall [ cfg.settings.web.port ]; + }; + + meta.maintainers = with maintainers; [ pizzapim ]; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index db24053e849a..c5d541c1577b 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -365,6 +365,7 @@ in { mimir = handleTest ./mimir.nix {}; gancio = handleTest ./gancio.nix {}; garage = handleTest ./garage {}; + gatus = runTest ./gatus.nix; gemstash = handleTest ./gemstash.nix {}; geoserver = runTest ./geoserver.nix; gerrit = handleTest ./gerrit.nix {}; diff --git a/nixos/tests/gatus.nix b/nixos/tests/gatus.nix new file mode 100644 index 000000000000..5bb146540fba --- /dev/null +++ b/nixos/tests/gatus.nix @@ -0,0 +1,34 @@ +{ pkgs, ... }: +{ + name = "gatus"; + meta.maintainers = with pkgs.lib.maintainers; [ pizzapim ]; + + nodes.machine = + { ... }: + { + services.gatus = { + enable = true; + + settings = { + web.port = 8080; + metrics = true; + + endpoints = [ + { + name = "metrics"; + url = "http://localhost:8080/metrics"; + interval = "1s"; + conditions = [ + "[STATUS] == 200" + ]; + } + ]; + }; + }; + }; + + testScript = '' + machine.wait_for_unit("gatus.service") + machine.succeed("curl -s http://localhost:8080/metrics | grep go_info") + ''; +}