Add wikijs for Aux

As part of the infra and docs teams for Auxolotl, we've decided to host
their wiki for them.

This was difficult for a few reasons
- They do not use Cloudflare, so our standard https certificate
  provisioning will not work
- They do not want our automatic www subdomains
- We already run wiki.js for TransPlace, and are not able to take that
  down. Nix doesn't allow us to add multiple wiki.js instances alongside
  each other
- This is not permanent, so we want to make it really easy to move to
  another server at a moment's notice, for example we don't want to tie
  it in to our postgres server

As a mitigation for these
- We override our normal ACME configuration. This forces cloudflare by
  default. We have added an "ugly hack" to avoid it forcing cloudflare
  for aux
- We update helpers to add a "specific" domain, i.e. do not add www
  aliases
- We use a nix container to host the wiki.js and another postgres server

Change-Id: Iecead03467f2b4a958d83cc6f92a8a0304323e35
Reviewed-on: https://git.clicks.codes/c/Infra/NixFiles/+/682
Tested-by: Skyler Grey <minion@clicks.codes>
Reviewed-by: Samuel Shuert <coded@clicks.codes>
diff --git a/flake.lock b/flake.lock
index 5194d71..2e37a76 100644
--- a/flake.lock
+++ b/flake.lock
@@ -252,11 +252,11 @@
         "nixpkgs": "nixpkgs_3"
       },
       "locked": {
-        "lastModified": 1700606678,
-        "narHash": "sha256-ZqkMRyAdrP7czMlOTqgZluaEvCRcwEGLRY9FZra/Yz8=",
+        "lastModified": 1714999005,
+        "narHash": "sha256-6i8DUM/6vvz+GlE+o3w6kWjIiBBzMf8ejk+t6pvPCmA=",
         "ref": "refs/heads/main",
-        "rev": "8b911b96cd322f9a3741d382cca30894617e4dad",
-        "revCount": 19,
+        "rev": "6706dbccf80b30a55243271fd9c8fd35ff1b453d",
+        "revCount": 20,
         "type": "git",
         "url": "https://git.clicks.codes/Infra/NixHelpers"
       },
diff --git a/helpers b/helpers
index 8b911b9..26ea07d 160000
--- a/helpers
+++ b/helpers
@@ -1 +1 @@
-Subproject commit 8b911b96cd322f9a3741d382cca30894617e4dad
+Subproject commit 26ea07d2bcf83bf7094ad3c38bd76c55d2e2572b
diff --git a/modules/common/aux.nix b/modules/common/aux.nix
new file mode 100644
index 0000000..501884f
--- /dev/null
+++ b/modules/common/aux.nix
@@ -0,0 +1,63 @@
+{
+  networking.nat = {
+    enable = true;
+    internalInterfaces = ["ve-aux-wikijs"];
+    externalInterface = "enp1s0";
+  };
+
+  containers.aux-wikijs = {
+    autoStart = true;
+    privateNetwork = true;
+
+    hostAddress = "10.0.101.1";
+    localAddress = "10.0.101.2";
+
+    config = { config, pkgs, lib, ... }: {
+      services.wiki-js = {
+        enable = true;
+
+        settings = {
+          bindIP = "0.0.0.0";
+          port = 1024;
+
+          db = {
+            host = "127.0.0.1";
+            user = "wiki";
+            pass = "internalonly";
+          };
+        };
+      };
+
+      system.stateVersion = "22.11";
+
+      services.postgresql = {
+        enable = true;
+        ensureDatabases = [
+          "wiki"
+        ];
+        ensureUsers = [
+          {
+            name = "wiki";
+            ensureDBOwnership = true;
+          }
+        ];
+      };
+
+      systemd.services.postgresql.postStart = ''
+        $PSQL -tAc "ALTER USER wiki PASSWORD 'internalonly';"
+      '';
+
+      networking = {
+        firewall = {
+          enable = true;
+          allowedTCPPorts = [ 1024 ];
+        };
+        # Use systemd-resolved inside the container
+        # Workaround for bug https://github.com/NixOS/nixpkgs/issues/162686
+        useHostResolvConf = lib.mkForce false;
+
+        nameservers = [ "1.1.1.1" "1.0.0.1" ];
+      };
+    };
+  };
+}
diff --git a/modules/common/nginx-routes.nix b/modules/common/nginx-routes.nix
index cb7004d..a4af2a8 100644
--- a/modules/common/nginx-routes.nix
+++ b/modules/common/nginx-routes.nix
@@ -30,6 +30,8 @@
 
       (ReverseProxy "generic:1035")
     ]))
+    (SpecificHost "wiki.auxolotl.org" (ReverseProxy "10.0.101.2:1024")) # see aux.nix
+    (SpecificHost "docs.auxolotl.org" (Path ''~ ^/?([^\r\n]*)$'' (Redirect "https://wiki.auxolotl.org/$1")))
     (Host "signup.hopescaramels.com" (ReverseProxy "caramels:1024"))
     (Host "freeflowtaekwondo.com" (ReverseProxy "generic:1026"))
     (Host "homebridge.coded.codes" (ReverseProxy "CodedPi:8581"))
diff --git a/modules/common/nginx.nix b/modules/common/nginx.nix
index 5bc99ad..38a2c74 100644
--- a/modules/common/nginx.nix
+++ b/modules/common/nginx.nix
@@ -8,6 +8,7 @@
             options = {
               host = lib.mkOption { type = str; };
               extraHosts = lib.mkOption { type = listOf str; };
+              specific = lib.mkOption { type = bool; };
               secure = lib.mkOption { type = bool; };
               service = lib.mkOption {
                 type = let
@@ -192,10 +193,14 @@
     users.users.nginx.extraGroups = [ config.users.users.acme.group ];
   };
 } (if base != null then {
-  config.security.acme.certs = lib.mkForce (builtins.mapAttrs (_: v:
-    (lib.filterAttrs (n: _: n != "directory" && n != "credentialsFile") v) // {
-      webroot = null;
-      dnsProvider = "cloudflare";
-    }) base.config.security.acme.certs);
+  config.security.acme.certs = lib.mkForce (builtins.mapAttrs (domain: v:
+    if builtins.match ".*\.auxolotl\.org" domain != null then
+      (lib.filterAttrs (n: _: n != "directory" && n != "credentialsFile") v)
+    else
+      (lib.filterAttrs (n: _: n != "directory" && n != "credentialsFile") v) // {
+        webroot = null;
+        dnsProvider = "cloudflare";
+      }
+    ) base.config.security.acme.certs);
 } else
   { })