zaphyra's git: nixfiles

zaphyra and void's nixfiles

commit b64f1b7d24d954e0014dcda36e3be85353146a78
parent 31b88bb707e3581bd4a48d6ee76feafeff29413a
Author: Katja (zaphyra) <git@ctu.cx>
Date: Fri, 6 Jun 2025 21:21:40 +0200

config/nixos/modules/websites: add `fedi.home.ctu.cx` (and enable on host `polaris`)
3 files changed, 200 insertions(+), 2 deletions(-)
A
config/nixos/modules/websites/fedi.home.ctu.cx.nix
|
193
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
M
hosts/polaris/default.nix
|
4
++++
M
secrets/polaris.yaml
|
5
+++--
diff --git a/config/nixos/modules/websites/fedi.home.ctu.cx.nix b/config/nixos/modules/websites/fedi.home.ctu.cx.nix
@@ -0,0 +1,193 @@
+{
+  name,
+  povSelf,
+  hostConfig,
+  config,
+  pkgs,
+  lib,
+  ...
+}:
+
+let
+  inherit (lib) types;
+  cfg = lib.getAttrFromPath povSelf config;
+  cfgWebsites = lib.getAttrFromPath (lib.remove name povSelf) config;
+
+in
+{
+
+  options = {
+    enable = {
+      type = types.bool;
+      default = false;
+    };
+    domain = {
+      type = types.str;
+      default = "ctu.cx";
+    };
+    subdomain = {
+      type = types.str;
+      default = "fedi.home";
+    };
+  };
+
+  config = lib.mkIf cfg.enable {
+    dns.zones."${cfg.domain}".subdomains."${cfg.subdomain}".CNAME = [ "${config.networking.fqdn}." ];
+
+    sops.secrets = {
+      "resticPasswords/gotosocial" = { };
+    };
+
+    systemd.tmpfiles.settings.gotosocial = {
+      "/var/lib/gotosocial/storage".d = {
+        user = config.modules.services.gotosocial.user;
+        group = config.modules.services.gotosocial.group;
+        mode = "750";
+        age = "-";
+      };
+    };
+
+    modules.services = {
+      resticBackup.paths = {
+        gotosocial = {
+          enable = true;
+          user = config.modules.services.gotosocial.user;
+          passwordFile = config.sops.secrets."resticPasswords/gotosocial".path;
+          sqliteDatabases = [
+            (lib.mkIf (
+              config.modules.services.gotosocial.settings.db-type == "sqlite"
+            ) config.modules.services.gotosocial.settings.db-address)
+          ];
+          paths = [
+            (lib.mkIf (
+              config.modules.services.gotosocial.settings.storage-backend == "local"
+            ) config.modules.services.gotosocial.settings.storage-local-base-path)
+            "${config.modules.services.gotosocial.stateDir}/backup.json"
+          ];
+          runBeforeBackup = ''${pkgs.gotosocial}/bin/gotosocial --config-path /etc/gotosocial.yaml admin export --path ${config.modules.services.gotosocial.stateDir}/backup.json'';
+        };
+      };
+      gotosocial = {
+        enable = true;
+        group = config.services.nginx.group;
+        settings = {
+          protocol = lib.mkDefault "https";
+
+          bind-address = lib.mkDefault "[::1]";
+          port = lib.mkDefault 8085;
+
+          trusted-proxies = lib.mkDefault [
+            "::1/128"
+            "172.17.0.0/24"
+          ];
+
+          db-type = lib.mkDefault "sqlite";
+          db-address = lib.mkDefault "${config.modules.services.gotosocial.stateDir}/db.sqlite";
+
+          storage-backend = lib.mkDefault "local";
+          storage-local-base-path = "${config.modules.services.gotosocial.stateDir}/storage";
+
+          host = "${cfg.subdomain}.${cfg.domain}";
+          account-domain = cfg.domain;
+
+          landing-page-user = "katja";
+
+          accounts-allow-custom-css = true;
+          accounts-registration-open = false;
+
+          instance-expose-peers = true;
+          instance-expose-suspended = true;
+          instance-expose-suspended-web = true;
+
+          instance-languages = [
+            "de"
+            "en-us"
+          ];
+
+          media-local-max-size = "50MiB";
+          media-remote-max-size = "50MiB";
+
+          media-remote-cache-days = 3;
+          media-cleanup-from = "01:00";
+        };
+      };
+    };
+
+    services.nginx = {
+      appendHttpConfig = ''
+        proxy_cache_path /var/cache/nginx keys_zone=gotosocial_ap_public_responses:10m inactive=1w;
+      '';
+      virtualHosts =
+        {
+          "${config.modules.services.gotosocial.settings.host}" = {
+            useACMEHost = lib.mkDefault "${config.networking.fqdn}";
+            forceSSL = lib.mkDefault true;
+            kTLS = lib.mkDefault true;
+            locations = {
+              "/" = {
+                proxyPass = "http://${toString config.modules.services.gotosocial.settings.bind-address}:${toString config.modules.services.gotosocial.settings.port}";
+                proxyWebsockets = true;
+              };
+
+              "~ /.well-known/(webfinger|host-meta)$" = {
+                proxyPass = "http://${toString config.modules.services.gotosocial.settings.bind-address}:${toString config.modules.services.gotosocial.settings.port}";
+                extraConfig = ''
+                  proxy_cache gotosocial_ap_public_responses;
+                  proxy_cache_background_update on;
+                  proxy_cache_key $scheme://$host$uri$is_args$query_string;
+                  proxy_cache_valid 200 10m;
+                  proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504 http_429;
+                  proxy_cache_lock on;
+                  add_header X-Cache-Status $upstream_cache_status;
+                '';
+              };
+
+              "~ ^\/users\/(?:[a-z0-9_\.]+)\/main-key$" = {
+                proxyPass = "http://${toString config.modules.services.gotosocial.settings.bind-address}:${toString config.modules.services.gotosocial.settings.port}";
+                extraConfig = ''
+                  proxy_cache gotosocial_ap_public_responses;
+                  proxy_cache_background_update on;
+                  proxy_cache_key $scheme://$host$uri;
+                  proxy_cache_valid 200 604800s;
+                  proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504 http_429;
+                  proxy_cache_lock on;
+
+                  add_header X-Cache-Status $upstream_cache_status;
+                '';
+              };
+
+              "/assets/".extraConfig = ''
+                alias ${config.modules.services.gotosocial.package}/share/web/assets/;
+                autoindex off;
+                expires max;
+                add_header Cache-Control "public, immutable";
+              '';
+            };
+          };
+        }
+        // (
+          if
+            (
+              config.modules.services.gotosocial.settings.account-domain
+              != config.modules.services.gotosocial.settings.host
+            )
+          then
+            {
+              "${config.modules.services.gotosocial.settings.account-domain}" = {
+                locations = {
+                  "= /.well-known/host-meta".extraConfig =
+                    "return 301 https://${config.modules.services.gotosocial.settings.host}$request_uri;";
+                  "= /.well-known/webfinger".extraConfig =
+                    "return 301 https://${config.modules.services.gotosocial.settings.host}$request_uri;";
+                  "= /.well-known/nodeinfo".extraConfig =
+                    "return 301 https://${config.modules.services.gotosocial.settings.host}$request_uri;";
+                };
+              };
+            }
+          else
+            { }
+        );
+    };
+  };
+
+}
diff --git a/hosts/polaris/default.nix b/hosts/polaris/default.nix
@@ -79,6 +79,10 @@
           };
         };
 
+        websites = {
+          "fedi.home.ctu.cx".enable = true;
+        };
+
         users.zaphyra.enable = true;
       };
 
diff --git a/secrets/polaris.yaml b/secrets/polaris.yaml
@@ -9,6 +9,7 @@ environments:
     influxdb2: ENC[AES256_GCM,data:GVEs92BPKe8Lv4VxVBnbjTTVHszVCZHmd/gTw/K4UscX4efwjldknLPOqAEPNF7SdoEEbX17dSA0BL8Gj68j4rhTPJMGluWOprfDAZ+gMpEglfbfU4P2J0WgrbgLZDj53kBx95NsysVWGaR14jyff0S5Ay5YgSo=,iv:FAjaA/VsW1KNRbsoyv79jW4ooRaYMUs7SiWJ1VQBlqU=,tag:iC+wAFXR8EcKd67OL+lIIw==,type:str]
 resticPasswords:
     influxdb2: ENC[AES256_GCM,data:OBGzj5IcuM7bvb2k/wg3qwisA5TC9qMNWU4KDP2OEUs=,iv:DqTNEVQDpmRB6MOKvyKJ6YuWdKpIIt1q6yfeTaFSiZI=,tag:rTPtLkP0d4mVb0fvSHIzlw==,type:str]
+    gotosocial: ENC[AES256_GCM,data:8bL/PtcqOhskUWFxvGAPURl2OIOdr1AgwvIZcpB4mmk=,iv:/Ft30MuCx7l+MmIEGIA+vRohG73Zkhtg8O8kHLbkpBE=,tag:3X9RfGR+qMogW9uL6Ki4Rw==,type:str]
 sops:
     age:
         - recipient: age1qyqy5we7zua06ppj654rgd6t7kyw3gem6hnexna98j60klyus4zq68cjlz

@@ -20,8 +21,8 @@ sops:
             SUhEaGg3dE9HTnJZVXU5cXZ1YkVVQTgKreIDmLNlNfHNW5XGDJdAN9WIHOQqKKLP
             yPTbVRLiDdAejAOTA89fR6Vz1hAGtoPQuQoIFQXBdd8TLmp2C5hH5A==
             -----END AGE ENCRYPTED FILE-----
-    lastmodified: "2025-06-03T13:50:14Z"
-    mac: ENC[AES256_GCM,data:CPJfG8ICl+Yed2rLoTYZCBjhagpocmVfglY8NRYvjUl0bMUU+L/kjt8jcUcDb3t9/Z3RHMhazx6H2KeEdFvQyj3tMozd41stEs08jn4yL8qHCamNUhPfJVKY7lDi8ocNObcB9oE6Db3LLKpsSSFEmvg7Sssy7M4XklMM2Z7Mlbs=,iv:H5u4xmUp53enQGN74GyTSM0//t1l+Kcg+S1AeNL9ykg=,tag:cLgOHf1fbKS5l0VBR0q9MQ==,type:str]
+    lastmodified: "2025-06-07T09:58:47Z"
+    mac: ENC[AES256_GCM,data:qS9JNAlA45AjBtaTW4DZQq/kl6GHz7pr8FXe+GUjQMbZNFy5ZPVTEEvxBQ93SYV7XN3XpjKfzLLbus7V+0gMHDEcz2Q7jEFpP7rzdrNbp0w0NEeOV7XFKnk35drQEcJ0+khcrMvfreWLHfCKaTI2x01ag/8tkBuFg8Wqr9tFCmU=,iv:XMY45Ax7rRnotd5be2ThfVcjZT2qU70sC6z0w1/NwVU=,tag:puZI/8HBQ0eG0IxgGIPihA==,type:str]
     pgp:
         - created_at: "2025-06-02T17:31:26Z"
           enc: |-