about summary refs log tree commit diff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--flake.nix35
-rw-r--r--lib/my.nix1
-rw-r--r--modules/common/common/nix/default.nix12
-rw-r--r--modules/common/profiles/default.nix1
-rw-r--r--modules/common/profiles/email.nix89
-rw-r--r--modules/common/profiles/headful.nix76
-rw-r--r--modules/nixos/default.nix2
-rw-r--r--modules/nixos/monitoring/default.nix154
-rw-r--r--modules/nixos/nsd.nix3
-rw-r--r--modules/nixos/ntfy.nix57
-rw-r--r--modules/nixos/redis.nix36
-rw-r--r--modules/nixos/unbound.nix39
-rw-r--r--modules/nixos/victoriametrics.nix46
-rw-r--r--nixosConfigurations/eonwe/default.nix1
-rw-r--r--nixosConfigurations/manwe/default.nix58
-rw-r--r--nixosConfigurations/manwe/mailserver.nix8
16 files changed, 392 insertions, 226 deletions
diff --git a/flake.nix b/flake.nix
index fc96852..a1fe2f5 100644
--- a/flake.nix
+++ b/flake.nix
@@ -145,6 +145,17 @@
     #     nixpkgs.follows = "nixpkgs";
     #   };
     # };
+    # alertmanager-gotify = {
+    #   type = "github";
+    #   owner = "pinpox";
+    #   repo = "alertmanager-ntfy";
+    #   ref = "main";
+    #   inputs = {
+    #     flake-compat.follows = "flake-compat";
+    #     flake-utils.follows = "flake-utils";
+    #     nixpkgs.follows = "nixpkgs";
+    #   };
+    # };
 
     flake-utils = {
       type = "github";
@@ -236,7 +247,6 @@
           overlays = [self.overlays.default];
         };
       in {
-        # TODO Add packages from `self.overlay.default`.
         packages = with lib;
           (mapAttrs (_: c: c.config.system.build.toplevel)
             (builtins.removeAttrs self.nixosConfigurations ["iso-arm" "iso-x86"]))
@@ -298,12 +308,23 @@
         darwinModules.nixfiles = import ./modules/darwin;
         darwinConfigurations = importConfigurations ./darwinConfigurations;
 
-        overlays.default = final: _: {
-          bruh = final.callPackage ./packages/bruh.nix {};
-          mpv-autosub = final.callPackage ./packages/mpv-autosub.nix {};
-          myip = final.callPackage ./packages/myip.nix {};
-          nixfiles = final.callPackage ./packages/nixfiles.nix {};
-          throttled = final.callPackage ./packages/throttled.nix {};
+        overlays.default = final: prev: rec {
+          bruh = prev.callPackage ./packages/bruh.nix {};
+          mpv-autosub = prev.callPackage ./packages/mpv-autosub.nix {};
+          myip = prev.callPackage ./packages/myip.nix {};
+          nixfiles = prev.callPackage ./packages/nixfiles.nix {};
+          throttled = prev.callPackage ./packages/throttled.nix {};
+          logcli = prev.grafana-loki.overrideAttrs (_: super: {
+            pname = "logcli";
+            subPackages = ["cmd/logcli"];
+            nativeBuildInputs = super.nativeBuildInputs ++ [final.installShellFiles];
+            postInstall = ''
+              installShellCompletion --cmd logcli \
+                --bash <($out/bin/logcli --completion--script-bash) \
+                --zsh <($out/bin/logcli --completion-script-zsh)
+            '';
+            preFixup = null;
+          });
         };
       });
 }
diff --git a/lib/my.nix b/lib/my.nix
index 03cb37a..96f26f3 100644
--- a/lib/my.nix
+++ b/lib/my.nix
@@ -168,6 +168,7 @@ with lib;
                 "gotify.${shire}"
                 "grafana.${shire}"
                 "loki.${shire}"
+                "ntfy.${shire}"
                 "prometheus.${shire}"
                 "radicale.${shire}"
                 "rss-bridge.${shire}"
diff --git a/modules/common/common/nix/default.nix b/modules/common/common/nix/default.nix
index b328e4c..45f8ed3 100644
--- a/modules/common/common/nix/default.nix
+++ b/modules/common/common/nix/default.nix
@@ -4,6 +4,7 @@
   lib,
   localUsername ? lib.my.username,
   pkgs,
+  pkgsPR,
   this,
   ...
 }:
@@ -98,16 +99,7 @@ with lib; {
           patches = [./patches/alejandra-no-ads.patch];
         });
 
-        logcli = super.grafana-loki.overrideAttrs (_: final: {
-          nativeBuildInputs = final.nativeBuildInputs ++ [pkgs.installShellFiles];
-          subPackages = ["cmd/logcli"];
-          postInstall = ''
-            installShellCompletion --cmd logcli \
-              --bash <($out/bin/logcli --completion--script-bash) \
-              --zsh <($out/bin/logcli --completion-script-zsh)
-          '';
-          preFixup = null;
-        });
+        inherit (pkgsPR "222519" "sha256-XQOs0rMs6GMXUZfzjYZiP7lTBOfqF3dsdWGr1rCQeH0=") grafanaPlugins;
       }
       // (with super; let
         np = nodePackages;
diff --git a/modules/common/profiles/default.nix b/modules/common/profiles/default.nix
index 06ddaf4..4f8fa4d 100644
--- a/modules/common/profiles/default.nix
+++ b/modules/common/profiles/default.nix
@@ -10,6 +10,7 @@ with lib; let
 in {
   imports = [
     ./dev
+    ./email.nix
     ./headful.nix
     ./headless.nix
     (mkAliasOptionModule ["colourScheme"] [
diff --git a/modules/common/profiles/email.nix b/modules/common/profiles/email.nix
new file mode 100644
index 0000000..e289c2e
--- /dev/null
+++ b/modules/common/profiles/email.nix
@@ -0,0 +1,89 @@
+{
+  config,
+  lib,
+  pkgs,
+  this,
+  ...
+}:
+with lib; let
+  cfg = config.nixfiles.modules.profiles.email.default;
+in {
+  options.nixfiles.modules.profiles.email.default.enable =
+    mkEnableOption "Local Email management" // {default = this.isHeadful;};
+
+  config = mkIf cfg.enable {
+    hm = {
+      accounts.email = {
+        maildirBasePath = "${config.my.home}/doc/mail";
+
+        accounts = let
+          mkAccount = attrs:
+            mkMerge [
+              {
+                mbsync = {
+                  enable = true;
+                  create = "both";
+                  expunge = "both";
+                  patterns = ["*"];
+                };
+                msmtp.enable = true;
+                mu.enable = true;
+                thunderbird = {
+                  enable = pkgs.stdenv.isLinux;
+                  settings = id: {
+                    "mail.identity.id_${id}.compose_html" = false;
+                    "mail.identity.id_${id}.reply_on_top" = 0;
+                  };
+                };
+              }
+              attrs
+            ];
+
+          pass = path: "${config.hm.programs.password-store.package}/bin/pass show ${path}";
+        in rec {
+          shire = mkAccount rec {
+            address = my.email;
+            aliases = [address "frodo@rohan.net" "azahi@shire.net"];
+            realName = my.fullname;
+            gpg = {
+              inherit (my.pgp) key;
+              signByDefault = true;
+              encryptByDefault = false;
+            };
+
+            primary = true;
+
+            imap = {
+              host = "shire.net";
+              port = 993;
+              tls.enable = true;
+            };
+            smtp = {
+              host = "shire.net";
+              port = 465;
+              tls.enable = true;
+            };
+            userName = "azahi@shire.net";
+            passwordCommand = pass "email/shire.net/azahi";
+          };
+
+          yahoo = mkAccount rec {
+            address = "admin@yahoo.com";
+            aliases = [address "admin@yahoo.com"];
+            realName = "Багавиев Азат";
+
+            flavor = "yahoo.com";
+            userName = "admin@yahoo.com";
+            passwordCommand = pass "email/yahoo.com/admin";
+          };
+        };
+      };
+
+      programs = {
+        mbsync.enable = true;
+        msmtp.enable = true;
+        mu.enable = true;
+      };
+    };
+  };
+}
diff --git a/modules/common/profiles/headful.nix b/modules/common/profiles/headful.nix
index ea36b91..2be1b87 100644
--- a/modules/common/profiles/headful.nix
+++ b/modules/common/profiles/headful.nix
@@ -19,6 +19,7 @@ in {
       aria2.enable = true;
       emacs.enable = true;
       mpv.enable = true;
+      nullmailer.enable = true;
       openssh.client.enable = true;
       password-store.enable = true;
     };
@@ -33,85 +34,10 @@ in {
 
         packages = with pkgs; [
           fd
-          logcli
           ripgrep
           ripgrep-all
           sd
         ];
-
-        sessionVariables.LOKI_ADDR = "https://loki.shire.net";
-      };
-
-      accounts.email = {
-        maildirBasePath = "${config.my.home}/mail";
-
-        accounts = let
-          mkAccount = attrs:
-            mkMerge [
-              {
-                mbsync = {
-                  enable = true;
-                  create = "both";
-                  expunge = "both";
-                  patterns = ["*"];
-                };
-                msmtp.enable = true;
-                mu.enable = true;
-                thunderbird = {
-                  enable = pkgs.stdenv.isLinux;
-                  settings = id: {
-                    "mail.identity.id_${id}.compose_html" = false;
-                    "mail.identity.id_${id}.reply_on_top" = 0;
-                  };
-                };
-              }
-              attrs
-            ];
-
-          pass = path: "${config.hm.programs.password-store.package}/bin/pass show ${path}";
-        in rec {
-          shire = mkAccount rec {
-            address = my.email;
-            aliases = [address "frodo@rohan.net" "azahi@shire.net"];
-            realName = my.fullname;
-            gpg = {
-              inherit (my.pgp) key;
-              signByDefault = true;
-              encryptByDefault = false;
-            };
-
-            primary = true;
-
-            imap = {
-              host = "shire.net";
-              port = 993;
-              tls.enable = true;
-            };
-            smtp = {
-              host = "shire.net";
-              port = 465;
-              tls.enable = true;
-            };
-            userName = "azahi@shire.net";
-            passwordCommand = pass "email/shire.net/azahi";
-          };
-
-          yahoo = mkAccount rec {
-            address = "admin@yahoo.com";
-            aliases = [address "admin@yahoo.com"];
-            realName = "Багавиев Азат";
-
-            flavor = "yahoo.com";
-            userName = "admin@yahoo.com";
-            passwordCommand = pass "email/yahoo.com/admin";
-          };
-        };
-      };
-
-      programs = {
-        mbsync.enable = true;
-        msmtp.enable = true;
-        mu.enable = true;
       };
     };
 
diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix
index 269ce39..3c4192d 100644
--- a/modules/nixos/default.nix
+++ b/modules/nixos/default.nix
@@ -36,6 +36,7 @@ _: {
     ./nginx.nix
     ./node-exporter.nix
     ./nsd.nix
+    ./ntfy.nix
     ./nullmailer.nix
     ./openssh.nix
     ./podman.nix
@@ -46,6 +47,7 @@ _: {
     ./psd.nix
     ./radarr.nix
     ./radicale.nix
+    ./redis.nix
     ./rss-bridge.nix
     ./rtorrent.nix
     ./searx.nix
diff --git a/modules/nixos/monitoring/default.nix b/modules/nixos/monitoring/default.nix
index 1108be6..6cdc2c9 100644
--- a/modules/nixos/monitoring/default.nix
+++ b/modules/nixos/monitoring/default.nix
@@ -1,78 +1,93 @@
 {
   config,
   lib,
+  pkgs,
   ...
 }:
 with lib; let
   cfg = config.nixfiles.modules.monitoring;
 in {
   options.nixfiles.modules.monitoring.enable = mkEnableOption ''
-    a custom monitoring stack bas on the Grafana Labs toolkit
+    a glue to provision a monitoring stack
   '';
 
   config = mkIf cfg.enable {
     nixfiles.modules = {
+      alertmanager.enable = true;
       grafana.enable = true;
       loki.enable = true;
       prometheus.enable = true;
-      alertmanager.enable = true;
     };
 
     services = {
-      grafana.provision = {
-        enable = true;
-
-        # https://grafana.com/docs/grafana/latest/administration/provisioning/#data-sources
-        datasources.settings.datasources = with config.nixfiles.modules; [
-          {
-            name = "Prometheus";
-            type = "prometheus";
-            access = "proxy";
-            url = "https://${prometheus.domain}";
-            isDefault = true;
-          }
-          {
-            name = "Loki";
-            type = "loki";
-            access = "proxy";
-            url = "https://${loki.domain}";
-          }
-          {
-            name = "Alertmanager";
-            type = "alertmanager";
-            access = "proxy";
-            jsonData.implementation = "prometheus";
-            url = "https://${alertmanager.domain}";
-          }
+      grafana = {
+        declarativePlugins = with pkgs.grafanaPlugins; [
+          redis-app
+          redis-datasource
+          redis-explorer-app
         ];
 
-        # https://grafana.com/docs/grafana/latest/administration/provisioning/#dashboards
-        dashboards.settings.providers = [
-          # System dashboard is imported manually from here[1]. Too bad
-          # provisioned dashboards cannot properly integrate dynamic datasources
-          # yet.
-          #
-          # [1]: https://grafana.com/grafana/dashboards/1860-node-exporter-full
-          {
-            name = "endlessh";
-            options.path = ./dashboards/endlessh.json;
-          }
-          {
-            name = "unbound";
-            options.path = ./dashboards/unbound.json;
-          }
-          {
-            name = "nginx";
-            options.path = ./dashboards/nginx.json;
-          }
-          {
-            name = "postgersql";
-            options.path = ./dashboards/postgresql.json;
-          }
-        ];
+        provision = {
+          enable = true;
 
-        alerting = {
-          contactPoints.settings.contactPoints = [
+          # https://grafana.com/docs/grafana/latest/administration/provisioning/#data-sources
+          datasources.settings.datasources = with config.nixfiles.modules; [
+            {
+              name = "Alertmanager";
+              type = "alertmanager";
+              access = "proxy";
+              jsonData.implementation = "prometheus";
+              url = "https://${alertmanager.domain}";
+            }
+            {
+              name = "Loki";
+              type = "loki";
+              access = "proxy";
+              url = "https://${loki.domain}";
+              isDefault = true;
+            }
+            {
+              name = "Prometheus";
+              type = "prometheus";
+              access = "proxy";
+              url = "https://${prometheus.domain}";
+            }
+            (mkIf config.nixfiles.modules.redis.enable {
+              name = "Redis";
+              type = "redis-datasource";
+              access = "proxy";
+              url = with config.services.redis.servers.default; "redis://${bind}:${toString port}";
+              jsonData.client = "standalone";
+            })
+          ];
+
+          # https://grafana.com/docs/grafana/latest/administration/provisioning/#dashboards
+          dashboards.settings.providers = [
+            # The System dashboard is imported manually from here[1]. Too bad
+            # provisioned dashboards cannot properly integrate dynamic datasources
+            # yet.
+            #
+            # [1]: https://grafana.com/grafana/dashboards/1860-node-exporter-full
+            {
+              name = "endlessh";
+              options.path = ./dashboards/endlessh.json;
+            }
+            {
+              name = "unbound";
+              options.path = ./dashboards/unbound.json;
+            }
+            {
+              name = "nginx";
+              options.path = ./dashboards/nginx.json;
+            }
+            {
+              name = "postgersql";
+              options.path = ./dashboards/postgresql.json;
+            }
+          ];
+
+          # https://grafana.com/docs/grafana/latest/administration/provisioning/#alerting
+          alerting.contactPoints.settings.contactPoints = [
             {
               name = "Alertmanager";
               receivers = [
@@ -84,25 +99,6 @@ in {
               ];
             }
           ];
-          muteTimings.settings.muteTimes = [
-            {
-              name = "Sleep";
-              time_intervals = [
-                {
-                  times = [
-                    {
-                      start_time = "23:00";
-                      end_time = "24:00";
-                    }
-                    {
-                      start_time = "00:00";
-                      end_time = "09:00";
-                    }
-                  ];
-                }
-              ];
-            }
-          ];
         };
       };
 
@@ -139,7 +135,6 @@ in {
                     mkTargets
                     [
                       manwe
-                      varda
                       yavanna
                     ]
                     nginx.port;
@@ -175,6 +170,19 @@ in {
               ];
             }
             {
+              job_name = "redis";
+              static_configs = [
+                {
+                  targets =
+                    mkTargets
+                    [
+                      manwe
+                    ]
+                    redis.port;
+                }
+              ];
+            }
+            {
               job_name = "unbound";
               static_configs = [
                 {
diff --git a/modules/nixos/nsd.nix b/modules/nixos/nsd.nix
index 0dade8f..d2ab117 100644
--- a/modules/nixos/nsd.nix
+++ b/modules/nixos/nsd.nix
@@ -112,13 +112,12 @@ in {
                       gotify = manwe;
                       grafana = manwe;
                       loki = manwe;
+                      ntfy = manwe;
                       prometheus = manwe;
                       radicale = manwe;
                       rss-bridge = manwe;
                       vaultwarden = manwe;
 
-                      minecraft = varda;
-
                       flood = yavanna;
                     };
                   }
diff --git a/modules/nixos/ntfy.nix b/modules/nixos/ntfy.nix
new file mode 100644
index 0000000..2fd3234
--- /dev/null
+++ b/modules/nixos/ntfy.nix
@@ -0,0 +1,57 @@
+{
+  config,
+  lib,
+  ...
+}:
+with lib; let
+  cfg = config.nixfiles.modules.ntfy;
+in {
+  options.nixfiles.modules.ntfy = {
+    enable = mkEnableOption "ntfy";
+
+    port = mkOption {
+      description = "Port.";
+      type = types.port;
+      default = 2586;
+    };
+
+    domain = mkOption {
+      description = "Domain name sans protocol scheme.";
+      type = with types; str;
+      default = "ntfy.${config.networking.domain}";
+    };
+  };
+
+  config = mkIf cfg.enable {
+    nixfiles.modules.nginx = {
+      enable = true;
+      upstreams.ntfy.servers.${config.services.ntfy-sh.settings.listen-http} = {};
+      virtualHosts.${cfg.domain} = {
+        locations."/" = {
+          proxyPass = "http://ntfy";
+          proxyWebsockets = true;
+        };
+        extraConfig = nginxInternalOnly;
+      };
+    };
+
+    services.ntfy-sh = {
+      enable = true;
+      settings = {
+        listen-http = "127.0.0.1:${toString cfg.port}";
+        base-url = "https://${cfg.domain}";
+        cache-file = "/var/cache/ntfy/cache.db";
+        behind-proxy = true;
+        attachment-cache-dir = "/var/cache/ntfy/attachments";
+        auth-file = "/var/lib/ntfy/user.db";
+        auth-default-access = "deny-all";
+      };
+    };
+
+    systemd.tmpfiles.rules = with config.services.ntfy-sh; [
+      "d /var/lib/ntfy 0700 ${user} ${group} - -"
+      "d /var/cache/ntfy 0700 ${user} ${group} - -"
+      "d /var/cache/ntfy/attachments 0700 ${user} ${group} - -"
+    ];
+  };
+}
diff --git a/modules/nixos/redis.nix b/modules/nixos/redis.nix
new file mode 100644
index 0000000..166407e
--- /dev/null
+++ b/modules/nixos/redis.nix
@@ -0,0 +1,36 @@
+{
+  config,
+  lib,
+  this,
+  ...
+}:
+with lib; let
+  cfg = config.nixfiles.modules.redis;
+in {
+  options.nixfiles.modules.redis.enable = mkEnableOption "Redis";
+
+  config = mkIf cfg.enable {
+    services = {
+      redis = {
+        servers.default = {
+          enable = true;
+          bind = "127.0.0.1";
+          port = 6379;
+        };
+        vmOverCommit = true;
+      };
+
+      prometheus.exporters = {
+        redis = {
+          enable = true;
+          listenAddress = mkDefault this.wireguard.ipv4.address;
+          port = mkDefault 9121;
+          extraFlags = with config.services.redis.servers.default; [
+            "--redis.addr=redis://${bind}:${toString port}"
+            "--redis.user=${user}"
+          ];
+        };
+      };
+    };
+  };
+}
diff --git a/modules/nixos/unbound.nix b/modules/nixos/unbound.nix
index 103e375..2291cc7 100644
--- a/modules/nixos/unbound.nix
+++ b/modules/nixos/unbound.nix
@@ -22,6 +22,8 @@ in {
     adblock-conf = "${config.services.unbound.stateDir}/adblock.conf";
   in
     mkIf cfg.enable {
+      nixfiles.modules.redis.enable = true;
+
       services = {
         unbound = {
           enable = true;
@@ -114,7 +116,7 @@ in {
               }
             ];
 
-            cachedb = with config.services.redis.servers.unbound; {
+            cachedb = with config.services.redis.servers.default; {
               backend = "redis";
               redis-server-host = bind;
               redis-server-port = port;
@@ -124,34 +126,13 @@ in {
           localControlSocketPath = "/run/unbound/unbound.socket";
         };
 
-        redis = {
-          servers.unbound = {
-            enable = true;
-            bind = "127.0.0.1";
-            port = 6379;
-          };
-          vmOverCommit = mkForce true;
-        };
-
-        prometheus.exporters = {
-          unbound = {
-            enable = true;
-            listenAddress = mkDefault this.wireguard.ipv4.address;
-            port = 9167;
-            fetchType = "uds";
-            controlInterface = config.services.unbound.localControlSocketPath;
-            inherit (config.services.unbound) group user;
-          };
-
-          redis = {
-            enable = true;
-            listenAddress = mkDefault this.wireguard.ipv4.address;
-            port = mkDefault 9121;
-            extraFlags = with config.services.redis.servers.unbound; [
-              "--redis.addr=redis://${bind}:${toString port}"
-              "--redis.user=${user}"
-            ];
-          };
+        prometheus.exporters.unbound = {
+          enable = true;
+          listenAddress = mkDefault this.wireguard.ipv4.address;
+          port = 9167;
+          fetchType = "uds";
+          controlInterface = config.services.unbound.localControlSocketPath;
+          inherit (config.services.unbound) group user;
         };
       };
 
diff --git a/modules/nixos/victoriametrics.nix b/modules/nixos/victoriametrics.nix
new file mode 100644
index 0000000..509ee17
--- /dev/null
+++ b/modules/nixos/victoriametrics.nix
@@ -0,0 +1,46 @@
+{
+  config,
+  lib,
+  ...
+}:
+with lib; let
+  cfg = config.nixfiles.modules.prometheus;
+in {
+  options.nixfiles.modules.prometheus = {
+    enable = mkEnableOption "VictoriaMetrics";
+
+    port = mkOption {
+      description = "Port.";
+      type = with types; port;
+      default = 30113;
+    };
+
+    domain = mkOption {
+      description = "Domain name sans protocol scheme.";
+      type = with types; str;
+      default = "victoriametrics.${config.networking.domain}";
+    };
+  };
+
+  config = mkIf cfg.enable {
+    nixfiles.modules.nginx = with cfg; {
+      enable = true;
+      upstreams.victoriametrics.servers."127.0.0.1:${toString cfg.port}" = {};
+      virtualHosts.${domain} = {
+        locations."/".proxyPass = "http://victoriametrics";
+        extraConfig = nginxInternalOnly;
+      };
+    };
+
+    services.victoriametrics = {
+      enable = true;
+
+      listenAddress = "127.0.0.1:${toString cfg.port}";
+
+      extraOptions = [
+        "-loggerLevel=WARN"
+        # TODO scrape_config
+      ];
+    };
+  };
+}
diff --git a/nixosConfigurations/eonwe/default.nix b/nixosConfigurations/eonwe/default.nix
index b5a5fc4..4c29013 100644
--- a/nixosConfigurations/eonwe/default.nix
+++ b/nixosConfigurations/eonwe/default.nix
@@ -25,7 +25,6 @@ with lib; {
     libvirtd.enable = true;
     qutebrowser.enable = true;
     mpd.enable = true;
-    nullmailer.enable = true;
   };
 
   hm = {
diff --git a/nixosConfigurations/manwe/default.nix b/nixosConfigurations/manwe/default.nix
index a47cd88..a3c16b0 100644
--- a/nixosConfigurations/manwe/default.nix
+++ b/nixosConfigurations/manwe/default.nix
@@ -1,6 +1,5 @@
 {
   config,
-  inputs,
   lib,
   ...
 }:
@@ -44,36 +43,37 @@ with lib; {
       domain = my.domain.azahi;
     };
     vaultwarden.enable = true;
+    ntfy.enable = true;
   };
 
-  # To play old LAN games with the boys.
-  secrets."wireguard-private-key-70".file = "${inputs.self}/secrets/wireguard-private-key-70";
-  networking = mkIf config.nixfiles.modules.wireguard.server.enable {
-    wireguard.interfaces.wg70 = {
-      ips = ["10.70.0.1/16"];
-      listenPort = 7070;
-      privateKeyFile = config.secrets."wireguard-private-key-70".path;
-      peers = [
-        {
-          publicKey = "@PUBLIC_KEY@";
-          allowedIPs = ["10.70.1.1/32"];
-        }
-        {
-          publicKey = "@PUBLIC_KEY@";
-          allowedIPs = ["10.70.1.2/32"];
-        }
-        {
-          publicKey = "@PUBLIC_KEY@";
-          allowedIPs = ["10.70.1.3/32"];
-        }
-        {
-          publicKey = "@PUBLIC_KEY@";
-          allowedIPs = ["10.70.1.4/32"];
-        }
-      ];
-    };
-    firewall.allowedUDPPorts = [7070];
-  };
+  # A VPN to play old LAN games with the boys.
+  # secrets."wireguard-private-key-70".file = "${inputs.self}/secrets/wireguard-private-key-70";
+  # networking = mkIf config.nixfiles.modules.wireguard.server.enable {
+  #   wireguard.interfaces.wg70 = {
+  #     ips = ["10.70.0.1/16"];
+  #     listenPort = 7070;
+  #     privateKeyFile = config.secrets."wireguard-private-key-70".path;
+  #     peers = [
+  #       {
+  #         publicKey = "@PUBLIC_KEY@";
+  #         allowedIPs = ["10.70.1.1/32"];
+  #       }
+  #       {
+  #         publicKey = "@PUBLIC_KEY@";
+  #         allowedIPs = ["10.70.1.2/32"];
+  #       }
+  #       {
+  #         publicKey = "@PUBLIC_KEY@";
+  #         allowedIPs = ["10.70.1.3/32"];
+  #       }
+  #       {
+  #         publicKey = "@PUBLIC_KEY@";
+  #         allowedIPs = ["10.70.1.4/32"];
+  #       }
+  #     ];
+  #   };
+  #   firewall.allowedUDPPorts = [7070];
+  # };
 
   boot = {
     loader.grub = {
diff --git a/nixosConfigurations/manwe/mailserver.nix b/nixosConfigurations/manwe/mailserver.nix
index e8d1781..b59f0a8 100644
--- a/nixosConfigurations/manwe/mailserver.nix
+++ b/nixosConfigurations/manwe/mailserver.nix
@@ -7,6 +7,8 @@
 with lib; {
   imports = [inputs.simple-nixos-mailserver.nixosModule];
 
+  nixfiles.modules.redis.enable = true;
+
   secrets = {
     dkim-key-azahi-cc = {
       file = "${inputs.self}/secrets/dkim-key-azahi-cc";
@@ -52,6 +54,12 @@ with lib; {
 
     lmtpSaveToDetailMailbox = "no";
 
+    redis = with config.services.redis.servers.default; {
+      address = bind;
+      inherit port;
+      password = requirePass;
+    };
+
     loginAccounts = with my.domain; {
       "azahi@${shire}" = {
         hashedPassword = "@HASHED_PASSWORD@";

Consider giving Nix/NixOS a try! <3