Unverified Commit 727fe21d authored by williamvds's avatar williamvds
Browse files

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.
parent 8f5d24c1
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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"
  ],
+1 −0
Original line number Diff line number Diff line
@@ -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
+19 −0
Original line number Diff line number Diff line
# 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.
+104 −0
Original line number Diff line number Diff line
{
  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 ];
  };
}