From 727fe21d5dce688c64a17359ae2737fb170ca6b6 Mon Sep 17 00:00:00 2001 From: williamvds Date: Mon, 28 Apr 2025 22:29:05 +0100 Subject: [PATCH] nixos/pihole-web: init Pihole's dashboard is a web app which visualises statistics from pihole-FTL (i.e. dnsmasq), shows query logs, and allows configuration. With this module, configuration is largely declarative and immutable, so settings can't be changed, but they can be viewed from the webpage. The admin page also allows regenerating the DNS ("gravity") database. --- nixos/doc/manual/redirects.json | 6 + nixos/modules/module-list.nix | 1 + nixos/modules/services/web-apps/pihole-web.md | 19 ++++ .../modules/services/web-apps/pihole-web.nix | 104 ++++++++++++++++++ 4 files changed, 130 insertions(+) create mode 100644 nixos/modules/services/web-apps/pihole-web.md create mode 100644 nixos/modules/services/web-apps/pihole-web.nix diff --git a/nixos/doc/manual/redirects.json b/nixos/doc/manual/redirects.json index 080756744e56..bde64c2c14e8 100644 --- a/nixos/doc/manual/redirects.json +++ b/nixos/doc/manual/redirects.json @@ -1463,6 +1463,12 @@ "module-services-networking-pihole-ftl-configuration": [ "index.html#module-services-networking-pihole-ftl-configuration" ], + "module-services-web-apps-pihole-web": [ + "index.html#module-services-web-apps-pihole-web" + ], + "module-services-web-apps-pihole-web-configuration": [ + "index.html#module-services-web-apps-pihole-web-configuration" + ], "ch-profiles": [ "index.html#ch-profiles" ], diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 303781f6645e..bdcf5021282c 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1629,6 +1629,7 @@ ./services/web-apps/photoprism.nix ./services/web-apps/phylactery.nix ./services/web-apps/pict-rs.nix + ./services/web-apps/pihole-web.nix ./services/web-apps/pingvin-share.nix ./services/web-apps/pixelfed.nix ./services/web-apps/plantuml-server.nix diff --git a/nixos/modules/services/web-apps/pihole-web.md b/nixos/modules/services/web-apps/pihole-web.md new file mode 100644 index 000000000000..0c6e89276031 --- /dev/null +++ b/nixos/modules/services/web-apps/pihole-web.md @@ -0,0 +1,19 @@ +# Pi-hole Web Dashboard {#module-services-web-apps-pihole-web} + +The Pi-hole suite provides a web GUI for controlling and monitoring +[pihole-FTL](index.html#module-services-networking-pihole-ftl). + +## Configuration {#module-services-web-apps-pihole-web-configuration} + +Example configuration: + +```nix +{ + services.pihole-web = { + enable = true; + ports = [ 80 ]; + }; +} +``` + +The dashboard can be configured using [{option}`services.pihole-ftl.settings`](options.html#opt-services.pihole-ftl.settings), in particular the `webserver` subsection. diff --git a/nixos/modules/services/web-apps/pihole-web.nix b/nixos/modules/services/web-apps/pihole-web.nix new file mode 100644 index 000000000000..fe62dec6afed --- /dev/null +++ b/nixos/modules/services/web-apps/pihole-web.nix @@ -0,0 +1,104 @@ +{ + config, + lib, + pkgs, + ... +}: + +let + cfg = config.services.pihole-web; +in +{ + options.services.pihole-web = { + enable = lib.mkEnableOption "Pi-hole dashboard"; + + package = lib.mkPackageOption pkgs "pihole-web" { }; + + hostName = lib.mkOption { + type = lib.types.str; + description = "Domain name for the website."; + default = "pi.hole"; + }; + + ports = + let + portType = lib.types.submodule { + options = { + port = lib.mkOption { + type = lib.types.port; + description = "Port to bind"; + }; + optional = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Skip the port if it cannot be bound"; + }; + redirectSSL = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Redirect from this port to the first configured SSL port"; + }; + ssl = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Serve SSL on the port"; + }; + }; + }; + in + lib.mkOption { + type = lib.types.listOf ( + lib.types.oneOf [ + lib.types.port + lib.types.str + portType + ] + ); + description = '' + Port(s) for the webserver to serve on. + + If provided as a string, optionally append suffixes to control behaviour: + + - `o`: to make the port is optional - failure to bind will not be an error. + - `s`: for the port to be used for SSL. + - `r`: for a non-SSL port to redirect to the first available SSL port. + ''; + example = [ + "80r" + "443s" + ]; + apply = + values: + let + convert = + value: + if (builtins.typeOf) value == "int" then + toString value + else if builtins.typeOf value == "set" then + lib.strings.concatStrings [ + (toString value.port) + (lib.optionalString value.optional "o") + (lib.optionalString value.redirectSSL "r") + (lib.optionalString value.ssl "s") + ] + else + value; + in + lib.strings.concatStringsSep "," (map convert values); + }; + }; + + config = lib.mkIf cfg.enable { + services.pihole-ftl.settings.webserver = { + domain = cfg.hostName; + port = cfg.ports; + paths.webroot = "${cfg.package}/share/"; + paths.webhome = "/"; + }; + }; + + meta = { + doc = ./pihole-web.md; + maintainers = with lib.maintainers; [ williamvds ]; + }; +}