zaphyra's git: nixfiles

zaphyra and void's nixfiles

commit 132c5f25ba280389d9eb86e8924e145ca0fdbd99
parent e846889b707d2e03b340de40f519c96fbf21e750
Author: Katja (zaphyra) <git@ctu.cx>
Date: Sat, 24 May 2025 17:59:39 +0200

config/nixos/modules/services: add `gotosocial`
1 file changed, 186 insertions(+), 0 deletions(-)
A
config/nixos/modules/services/gotosocial.nix
|
186
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/config/nixos/modules/services/gotosocial.nix b/config/nixos/modules/services/gotosocial.nix
@@ -0,0 +1,186 @@
+{
+  povSelf,
+  config,
+  lib,
+  pkgs,
+  ...
+}:
+let
+  inherit (lib) types;
+  cfg = lib.getAttrFromPath povSelf config;
+  settingsFormat = pkgs.formats.json { };
+
+in
+{
+
+  options = {
+    enable = {
+      type = types.bool;
+      default = false;
+    };
+
+    package = {
+      type = types.package;
+      default = pkgs.gotosocial;
+    };
+
+    user = {
+      type = types.str;
+      default = "gotosocial";
+    };
+
+    group = {
+      type = types.str;
+      default = "gotosocial";
+    };
+
+    stateDir = {
+      type = types.str;
+      default = "/var/lib/gotosocial";
+      readOnly = true;
+    };
+
+    environmentFile = {
+      type = with types; nullOr path;
+      default = null;
+    };
+
+    settings = {
+      default = { };
+      description = ''
+        Configuration for GoToSocial, see
+        <link xlink:href="https://docs.gotosocial.org/en/latest/">
+        for supported values.
+      '';
+      type = types.submodule {
+        freeformType = settingsFormat.type;
+        options = {
+          host = lib.mkOption {
+            type = lib.types.nullOr lib.types.str;
+            default = null;
+            description = ''
+              Hostname that this server will be reachable at. Defaults to localhost for local testing,
+              but you should *definitely* change this when running for real, or your server won't work at all.
+              DO NOT change this after your server has already run once, or you will break things!
+            '';
+          };
+          port = lib.mkOption {
+            type = lib.types.port;
+            default = 8080;
+            description = ''
+              Int. Listen port for the GoToSocial webserver + API. If you're running behind a reverse proxy and/or in a docker,
+              container, just set this to whatever you like (or leave the default), and make sure it's forwarded properly.
+              If you are running with built-in letsencrypt enabled, and running GoToSocial directly on a host machine, you will
+              probably want to set this to 443 (standard https port), unless you have other services already using that port.
+              This *MUST NOT* be the same as the letsencrypt port specified below, unless letsencrypt is turned off.
+            '';
+          };
+        };
+      };
+    };
+  };
+
+  config = lib.mkIf cfg.enable (
+    let
+      configFile = settingsFormat.generate "gotosocial-config.yaml" cfg.settings;
+    in
+    {
+      assertions = [
+        {
+          assertion = cfg.settings.host != null;
+          message = "You have to define a hostname for GoToSocial, it cannot be changed later without starting over!";
+        }
+      ];
+
+      modules.services.gotosocial.settings = {
+        # Defaults
+        user = lib.mkDefault cfg.user;
+        group = lib.mkDefault cfg.group;
+
+        storage-local-base-path = lib.mkDefault cfg.stateDir;
+
+        web-template-base-dir = lib.mkDefault "${cfg.package}/share/web/template/";
+        web-asset-base-dir = lib.mkDefault "${cfg.package}/share/web/assets/";
+      };
+
+      users = {
+        users."${cfg.user}" = {
+          home = cfg.stateDir;
+          group = cfg.group;
+          isSystemUser = true;
+        };
+        groups."${cfg.group}" = { };
+      };
+
+      environment.etc."gotosocial.yaml".source = configFile;
+
+      environment.systemPackages = [
+        (pkgs.writeShellScriptBin "gotosocial" ''
+          exec ${cfg.package}/bin/gotosocial --config-path ${configFile} "$@"
+        '')
+      ];
+
+      systemd.services = {
+        gotosocial = {
+          description = "GoToSocial ActivityPub Server";
+          wants = [ "network-online.target" ];
+          after = [ "network-online.target" ];
+          wantedBy = [ "multi-user.target" ];
+          environment = {
+            GTS_WAZERO_COMPILATION_CACHE = "${cfg.stateDir}/.cache";
+          };
+
+          serviceConfig = {
+            User = cfg.user;
+            Group = cfg.group;
+
+            Type = "exec";
+            WorkingDirectory = "~";
+            StateDirectory = lib.mkIf (
+              cfg.settings.storage-local-base-path != "/var/lib/gotosocial"
+            ) "gotosocial";
+            ReadOnlyPaths = [ cfg.package ];
+            ReadWritePaths = [ cfg.settings.storage-local-base-path ];
+            StateDirectoryMode = "750";
+
+            Restart = "always";
+            RestartSec = 3;
+
+            EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile;
+            ExecStart = "${cfg.package}/bin/gotosocial --config-path ${configFile} server start";
+
+            NoNewPrivileges = true;
+            PrivateTmp = true;
+            PrivateDevices = false;
+
+            RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
+            RestrictNamespaces = true;
+            RestrictRealtime = true;
+
+            ProtectSystem = "full";
+            ProtectControlGroups = true;
+            ProtectKernelModules = true;
+            ProtectKernelTunables = true;
+
+            DevicePolicy = "closed";
+            LockPersonality = true;
+            SystemCallFilter = "~@clock @debug @module @mount @obsolete @reboot @setuid @swap";
+
+            CapabilityBoundingSet = [
+              "~CAP_RAWIO CAP_MKNOD"
+              "~CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_AUDIT_WRITE"
+              "~CAP_SYS_BOOT CAP_SYS_TIME CAP_SYS_MODULE CAP_SYS_PACCT"
+              "~CAP_LEASE CAP_LINUX_IMMUTABLE CAP_IPC_LOCK"
+              "~CAP_BLOCK_SUSPEND CAP_WAKE_ALARM"
+              "~CAP_SYS_TTY_CONFIG"
+              "~CAP_MAC_ADMIN CAP_MAC_OVERRIDE"
+              "~CAP_NET_ADMIN CAP_NET_BROADCAST CAP_NET_RAW"
+              "~CAP_SYS_ADMIN CAP_SYS_PTRACE CAP_SYSLOG"
+            ];
+          };
+        };
+      };
+    }
+  );
+
+}