zaphyra's git: nixfiles

zaphyra's nixfiles

commit b38373d12931818aa44927056aef39acc2a7a58e
parent 328996676f09e23a1420fd210ca01ffca9e508d8
Author: Katja Ramona Sophie Kwast (zaphyra) <git@zaphyra.eu>
Date: Thu, 21 Aug 2025 21:19:07 +0200

cleanup (remove stuff thats in tgcNUR now)
26 files changed, 236 insertions(+), 1093 deletions(-)
M
config/home-manager/common/home.nix
|
1
+
M
config/home-manager/zaphyra/configure/gnome.nix
|
4
++--
M
config/home-manager/zaphyra/configure/niri.nix
|
4
++--
M
config/home-manager/zaphyra/programs/chaosctl.nix
|
6
+++---
M
config/home-manager/zaphyra/programs/swaylock.nix
|
2
+-
M
config/home-manager/zaphyra/services/shaderbg.nix
|
19
++++++-------------
M
config/nixos/modules/presets/zaphyra/mautrixBridges/signal.nix
|
3
+--
M
config/nixos/modules/presets/zaphyra/mautrixBridges/telegram.nix
|
4
++--
M
config/nixos/modules/presets/zaphyra/mautrixBridges/whatsapp.nix
|
2
+-
D
config/nixos/modules/services/gotosocial.nix
|
198
-------------------------------------------------------------------------------
D
config/nixos/modules/services/mautrixBridge.nix
|
156
-------------------------------------------------------------------------------
M
config/nixos/modules/websites/fedi.ctu.cx.nix
|
140
++++++++++++++++++++++++++++++++++++++++---------------------------------------
M
config/nixos/modules/websites/fedi.home.ctu.cx.nix
|
136
++++++++++++++++++++++++++++++++++++++++----------------------------------------
M
config/nixos/modules/websites/gomuks.zaphyra.eu.nix
|
7
+------
M
config/nixos/modules/websites/gts.zaphyra.eu.nix
|
147
++++++++++++++++++++++++++++++++++++++++---------------------------------------
M
flake.nix
|
6
++----
D
overlays/tuigreet.nix
|
20
--------------------
D
packages/adwaita-colors-icon-theme.nix
|
41
-----------------------------------------
D
packages/chaosctl/chaosctl.fish
|
65
-----------------------------------------------------------------
D
packages/chaosctl/default.nix
|
5
-----
D
packages/gotosocial/default.nix
|
99
-------------------------------------------------------------------------------
D
packages/mautrix-telegramgo.nix
|
48
------------------------------------------------
D
packages/phanpy.nix
|
46
----------------------------------------------
D
packages/shaderbg.nix
|
47
-----------------------------------------------
D
packages/sointu.nix
|
64
----------------------------------------------------------------
D
packages/wlsbg.nix
|
59
-----------------------------------------------------------
diff --git a/config/home-manager/common/home.nix b/config/home-manager/common/home.nix
@@ -12,6 +12,7 @@
     inputs.sopsNix.homeManagerModules.sops
     inputs.sherlock.homeManagerModules.default
     inputs.airpodsctl.homeManagerModules.kairpodsd
+    inputs.tgcNUR.homeManagerModules.default
   ];
 
   home.stateVersion = lib.mkDefault "25.05";
diff --git a/config/home-manager/zaphyra/configure/gnome.nix b/config/home-manager/zaphyra/configure/gnome.nix
@@ -50,7 +50,7 @@ in
 
     iconTheme = {
       name = "Adwaita-green";
-      package = pkgs.adwaita-colors-icon-theme;
+      package = pkgs.tgc.adwaita-colors-icon-theme;
     };
 
     cursorTheme = {

@@ -156,7 +156,7 @@ in
         command = "${pkgs.writeShellScript "cccda-buzzer" ''
           export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
 
-          ${pkgs.libnotify}/bin/notify-send -e "CCCDA-Door" "$(${pkgs.chaosctl}/bin/chaosctl door buzzer)"
+          ${lib.getExe' pkgs.libnotify "notify-send"} -e "CCCDA-Door" "$(${lib.getExe pkgs.tgc.chaosctl} door buzzer)"
         ''}";
         binding = "<Super><Shift>d";
       };
diff --git a/config/home-manager/zaphyra/configure/niri.nix b/config/home-manager/zaphyra/configure/niri.nix
@@ -59,8 +59,8 @@ in
     enable = true;
 
     iconTheme = {
-      name = "Adwaita";
-      package = pkgs.adwaita-icon-theme;
+      name = "Adwaita-green";
+      package = pkgs.tgc.adwaita-colors-icon-theme;
     };
 
     cursorTheme = {
diff --git a/config/home-manager/zaphyra/programs/chaosctl.nix b/config/home-manager/zaphyra/programs/chaosctl.nix
@@ -7,12 +7,12 @@
 
 {
 
-  home.packages = [ pkgs.chaosctl ];
+  home.packages = [ pkgs.tgc.chaosctl ];
 
   programs.niri.settings.binds = with config.lib.niri.actions; {
     "Mod+Shift+D".action = spawn "${pkgs.writeShellScript "cccda-buzzer" ''
-      export SSH_AUTH_SOCK=$(${pkgs.gnupg}/bin/gpgconf --list-dirs agent-ssh-socket)
-      ${pkgs.libnotify}/bin/notify-send -e "CCCDA-Door" "$(${lib.getExe pkgs.chaosctl} door buzzer)"
+      export SSH_AUTH_SOCK=$(${lib.getExe' pkgs.gnupg "gpgconf"} --list-dirs agent-ssh-socket)
+      ${lib.getExe' pkgs.libnotify "notify-send"} -e "CCCDA-Door" "$(${lib.getExe pkgs.tgc.chaosctl} door buzzer)"
     ''}";
   };
 
diff --git a/config/home-manager/zaphyra/programs/swaylock.nix b/config/home-manager/zaphyra/programs/swaylock.nix
@@ -18,7 +18,7 @@
       ring-color = "4aa96c";
       show-failed-attempts = true;
 
-      command = "${lib.getExe pkgs.shaderbg} '*' --fps 10 ${inputs.self.resources.shaders.background1}";
+      command = "${lib.getExe pkgs.tgc.shaderbg} '*' --fps 10 ${inputs.self.resources.shaders.background1}";
 
       # image = "/home/zaphyra/Pictures/Backgrounds/lock.png";
       # scaling = "fit";
diff --git a/config/home-manager/zaphyra/services/shaderbg.nix b/config/home-manager/zaphyra/services/shaderbg.nix
@@ -1,18 +1,11 @@
-{ inputs, pkgs, lib, ... }:
+{ inputs, ... }:
 
 {
-
-  systemd.user.services.shaderbg = {
-    Unit = {
-      Description = "A live wallpaper program for Sway and other compositors with wlr-layer-shell support.";
-      After = [ "graphical-session.target" ];
-    };
-    Service = {
-      ExecStart = "${lib.getExe pkgs.shaderbg} '*' --fps 10 ${inputs.self.resources.shaders.background1}";
-      Restart = "on-failure";
-      RestartSec = 5;
-    };
-    Install.WantedBy = [ "graphical-session.target" ];
+  tgc.services.shaderbg = {
+    enable = true;
+    systemd.enable = true;
+    systemd.extraArgs = [ "--fps" "10" ];
+    systemd.shaderFile = inputs.self.resources.shaders.background1;
   };
 
 }
diff --git a/config/nixos/modules/presets/zaphyra/mautrixBridges/signal.nix b/config/nixos/modules/presets/zaphyra/mautrixBridges/signal.nix
@@ -3,7 +3,6 @@
   pkgs,
   lib,
   config,
-  hostConfig,
   ...
 }:
 let

@@ -28,7 +27,7 @@ in
 
     sops.secrets."environments/mautrixBridges/signal" = { };
 
-    modules.services.mautrixBridge.signal = {
+    tgc.services.mautrixBridge.signal = {
       enable = true;
       package = pkgs.mautrix-signal.override { withGoolm = true; };
       environmentFile = config.sops.secrets."environments/mautrixBridges/signal".path;
diff --git a/config/nixos/modules/presets/zaphyra/mautrixBridges/telegram.nix b/config/nixos/modules/presets/zaphyra/mautrixBridges/telegram.nix
@@ -28,9 +28,9 @@ in
 
     sops.secrets."environments/mautrixBridges/telegram" = { };
 
-    modules.services.mautrixBridge.telegram = {
+    tgc.services.mautrixBridge.telegram = {
       enable = true;
-      package = pkgs.mautrix-telegramgo.override { withGoolm = true; };
+      package = pkgs.tgc.mautrix-telegramgo;
       environmentFile = config.sops.secrets."environments/mautrixBridges/telegram".path;
       serviceDependencies = [ "grapevine.service" ];
       settings = rec {
diff --git a/config/nixos/modules/presets/zaphyra/mautrixBridges/whatsapp.nix b/config/nixos/modules/presets/zaphyra/mautrixBridges/whatsapp.nix
@@ -28,7 +28,7 @@ in
 
     sops.secrets."environments/mautrixBridges/whatsapp" = { };
 
-    modules.services.mautrixBridge.whatsapp = {
+    tgc.services.mautrixBridge.whatsapp = {
       enable = true;
       package = pkgs.mautrix-whatsapp.override { withGoolm = true; };
       serviceDependencies = [ "grapevine.service" ];
diff --git a/config/nixos/modules/services/gotosocial.nix b/config/nixos/modules/services/gotosocial.nix
@@ -1,198 +0,0 @@
-{
-  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.filesystem.impermanence.system.dirs = [
-        {
-          directory = cfg.stateDir;
-          mode = "0755";
-          user = cfg.user;
-          group = cfg.group;
-        }
-      ];
-
-      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"
-            "sops-install-secrets.service"
-          ];
-          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"
-            ];
-          };
-        };
-      };
-    }
-  );
-
-}
diff --git a/config/nixos/modules/services/mautrixBridge.nix b/config/nixos/modules/services/mautrixBridge.nix
@@ -1,156 +0,0 @@
-{
-  povSelf,
-  config,
-  lib,
-  pkgs,
-  ...
-}:
-let
-  inherit (lib) types;
-  cfg = lib.getAttrFromPath povSelf config;
-  forEachInstance =
-    f: lib.flip lib.mapAttrs' cfg (name: cfg: lib.nameValuePair "mautrixBridge-${name}" (f name cfg));
-
-in
-{
-
-  option = {
-    default = { };
-    type = types.attrsOf (
-      types.submodule ({
-        options = {
-          enable = lib.mkOption {
-            type = types.bool;
-            default = false;
-          };
-          package = lib.mkOption {
-            type = types.package;
-          };
-          settings = lib.mkOption {
-            type = (pkgs.formats.json { }).type;
-            default = { };
-          };
-          environmentFile = lib.mkOption {
-            type = with types; nullOr path;
-            default = null;
-          };
-          serviceDependencies = lib.mkOption {
-            type = with types; listOf str;
-            default = [ ];
-          };
-        };
-      })
-    );
-  };
-
-  config = {
-    modules.filesystem.impermanence.system.dirs = (
-      (lib.attrNames cfg) |> lib.map (element: "/var/lib/private/mautrix-${element}")
-    );
-
-    systemd.services = forEachInstance (
-      name: cfg:
-      let
-        dataDir = "/var/lib/mautrix-${name}";
-        registrationFile = "${dataDir}/registration.yaml";
-        settingsFile = "${dataDir}/config.yaml";
-        settingsFileUnsubstituted =
-          (pkgs.formats.json { }).generate "mautrix-${name}-config-unsubstituted.json"
-            cfg.settings;
-      in
-      {
-        enable = cfg.enable;
-        description = "mautrixBridge-${name}, a matrix puppeting bridge.";
-        restartTriggers = [ settingsFileUnsubstituted ];
-
-        wantedBy = [ "multi-user.target" ];
-        wants = [ "network-online.target" ] ++ cfg.serviceDependencies;
-        after = [ "network-online.target" ] ++ cfg.serviceDependencies;
-
-        path = [ pkgs.ffmpeg-headless ];
-
-        preStart = ''
-          # substitute the settings file by environment variables
-          # in this case read from EnvironmentFile
-          test -f '${settingsFile}' && rm -f '${settingsFile}'
-          old_umask=$(umask)
-          umask 0177
-          ${pkgs.envsubst}/bin/envsubst \
-            -o '${settingsFile}' \
-            -i '${settingsFileUnsubstituted}'
-          umask $old_umask
-
-          # generate the appservice's registration file if absent
-          if [ ! -f '${registrationFile}' ]; then
-            ${lib.getExe cfg.package} \
-              --generate-registration \
-              --config='${settingsFile}' \
-              --registration='${registrationFile}'
-          fi
-          chmod 640 ${registrationFile}
-
-          umask 0177
-          ${pkgs.yq}/bin/yq -s '
-              .[0].appservice.as_token = (.[0].appservice.as_token // .[1].as_token)
-            | .[0].appservice.hs_token = (.[0].appservice.hs_token // .[1].hs_token)
-          ${lib.optionalString (
-            name == "telegram"
-          ) "
-          | .[0].network.api_id = (.[0].network.api_id | tonumber)
-        "}
-            | .[0]' \
-            '${settingsFile}' '${registrationFile}' > '${settingsFile}.tmp'
-          mv '${settingsFile}.tmp' '${settingsFile}'
-          umask $old_umask
-        '';
-
-        serviceConfig = {
-          Type = "exec";
-
-          DynamicUser = true;
-          User = "mautrixBridge-${name}";
-          Group = "mautrixBridge-${name}";
-
-          EnvironmentFile = cfg.environmentFile;
-          StateDirectory = baseNameOf dataDir;
-          WorkingDirectory = dataDir;
-          UMask = 27;
-
-          ExecStart = ''
-            ${lib.getExe cfg.package} \
-            --no-update \
-            --config='${settingsFile}'
-          '';
-
-          Restart = "on-failure";
-          RestartSec = "30s";
-
-          LockPersonality = true;
-          NoNewPrivileges = true;
-          MemoryDenyWriteExecute = lib.mkIf (name != "signal") true;
-
-          PrivateDevices = true;
-          PrivateTmp = true;
-          PrivateUsers = true;
-
-          ProtectSystem = "strict";
-          ProtectClock = true;
-          ProtectHome = true;
-          ProtectHostname = true;
-          ProtectKernelLogs = true;
-          ProtectKernelModules = true;
-          ProtectKernelTunables = true;
-          ProtectControlGroups = true;
-
-          RestrictRealtime = true;
-          RestrictSUIDSGID = true;
-
-          SystemCallArchitectures = "native";
-          SystemCallErrorNumber = "EPERM";
-          SystemCallFilter = [ "@system-service" ];
-        };
-      }
-    );
-  };
-
-}
diff --git a/config/nixos/modules/websites/fedi.ctu.cx.nix b/config/nixos/modules/websites/fedi.ctu.cx.nix
@@ -1,7 +1,6 @@
 {
   name,
   povSelf,
-  hostConfig,
   config,
   pkgs,
   lib,

@@ -21,25 +20,17 @@ in
       type = types.bool;
       default = false;
     };
-    domain = {
-      type = types.str;
-      default = "ctu.cx";
-    };
-    subdomain = {
-      type = types.str;
-      default = "fedi";
-    };
   };
 
   config = lib.mkIf cfg.enable {
     assertions = [
       {
-        assertion = cfgWebsites."${cfg.domain}".enable == true;
-        message = "The option 'modules.websites.\"${cfg.domain}\"' must be enabled in order to use this module.";
+        assertion = cfgWebsites."ctu.cx}".enable == true;
+        message = "The option 'modules.websites.\"ctu.cx\"' must be enabled in order to use this module.";
       }
     ];
 
-    dns.zones."${cfg.domain}".subdomains."${cfg.subdomain}".CNAME = [ "${config.networking.fqdn}." ];
+    dns.zones."ctu.cx".subdomains."fedi".CNAME = [ "${config.networking.fqdn}." ];
 
     systemd.services.gotosocial.after = [ "sops-install-secrets.service" ];
     sops.secrets = {

@@ -51,77 +42,88 @@ in
 
     systemd.tmpfiles.settings.gotosocial = {
       "/var/lib/gotosocial/storage".d = {
-        user = config.modules.services.gotosocial.user;
-        group = config.modules.services.gotosocial.group;
+        user = config.tgc.services.gotosocial.user;
+        group = config.tgc.services.gotosocial.group;
         mode = "750";
         age = "-";
       };
     };
 
-    modules.services = {
-      resticBackup.paths = {
+    modules = {
+      filesystem.impermanence.system.dirs = [
+        {
+          directory = config.tgc.services.gotosocial.stateDir;
+          mode = "0755";
+          user = config.tgc.services.gotosocial.user;
+          group = config.tgc.services.gotosocial.group;
+        }
+      ];
+
+      services.resticBackup.paths = {
         gotosocial = {
           enable = true;
-          user = config.modules.services.gotosocial.user;
+          user = config.tgc.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)
+              config.tgc.services.gotosocial.settings.db-type == "sqlite"
+            ) config.tgc.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"
+              config.tgc.services.gotosocial.settings.storage-backend == "local"
+            ) config.tgc.services.gotosocial.settings.storage-local-base-path)
+            "${config.tgc.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'';
+          runBeforeBackup = ''${config.tgc.services.gotosocial.package}/bin/gotosocial --config-path /etc/gotosocial.yaml admin export --path ${config.tgc.services.gotosocial.stateDir}/backup.json'';
         };
       };
-      gotosocial = {
-        enable = true;
-        group = config.services.nginx.group;
-        environmentFile = config.sops.secrets."environments/gotosocial".path;
-        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";
+    tgc.services.gotosocial = {
+      enable = true;
+      package = pkgs.tgc.gotosocial-unstable;
+      group = config.services.nginx.group;
+      environmentFile = config.sops.secrets."environments/gotosocial".path;
+      settings = {
+        protocol = "https";
 
-          storage-backend = lib.mkDefault "local";
-          storage-local-base-path = "${config.modules.services.gotosocial.stateDir}/storage";
+        bind-address = "[::1]";
+        port = 8085;
 
-          host = "${cfg.subdomain}.${cfg.domain}";
-          account-domain = cfg.domain;
+        trusted-proxies = [
+          "::1/128"
+          "172.17.0.0/24"
+        ];
 
-          landing-page-user = "katja";
+        db-type = "sqlite";
+        db-address = "${config.tgc.services.gotosocial.stateDir}/db.sqlite";
 
-          accounts-allow-custom-css = true;
-          accounts-registration-open = false;
+        storage-backend = "local";
+        storage-local-base-path = "${config.tgc.services.gotosocial.stateDir}/storage";
 
-          instance-expose-peers = true;
-          instance-expose-suspended = true;
-          instance-expose-suspended-web = true;
+        host = "fedi.ctu.cx";
+        account-domain = "ctu.cx";
 
-          instance-languages = [
-            "de"
-            "en-us"
-          ];
+        landing-page-user = "katja";
 
-          media-local-max-size = "50MiB";
-          media-remote-max-size = "50MiB";
+        accounts-allow-custom-css = true;
+        accounts-registration-open = false;
 
-          media-remote-cache-days = 3;
-          media-cleanup-from = "01:00";
-        };
+        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";
       };
     };
 

@@ -131,18 +133,18 @@ in
       '';
       virtualHosts =
         {
-          "${config.modules.services.gotosocial.settings.host}" = {
+          "${config.tgc.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}";
+                proxyPass = "http://${toString config.tgc.services.gotosocial.settings.bind-address}:${toString config.tgc.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}";
+                proxyPass = "http://${toString config.tgc.services.gotosocial.settings.bind-address}:${toString config.tgc.services.gotosocial.settings.port}";
                 extraConfig = ''
                   proxy_cache gotosocial_ap_public_responses;
                   proxy_cache_background_update on;

@@ -155,7 +157,7 @@ in
               };
 
               "~ ^\/users\/(?:[a-z0-9_\.]+)\/main-key$" = {
-                proxyPass = "http://${toString config.modules.services.gotosocial.settings.bind-address}:${toString config.modules.services.gotosocial.settings.port}";
+                proxyPass = "http://${toString config.tgc.services.gotosocial.settings.bind-address}:${toString config.tgc.services.gotosocial.settings.port}";
                 extraConfig = ''
                   proxy_cache gotosocial_ap_public_responses;
                   proxy_cache_background_update on;

@@ -169,7 +171,7 @@ in
               };
 
               "/assets/".extraConfig = ''
-                alias ${config.modules.services.gotosocial.package}/share/web/assets/;
+                alias ${config.tgc.services.gotosocial.package}/share/web/assets/;
                 autoindex off;
                 expires max;
                 add_header Cache-Control "public, immutable";

@@ -180,19 +182,19 @@ in
         // (
           if
             (
-              config.modules.services.gotosocial.settings.account-domain
-              != config.modules.services.gotosocial.settings.host
+              config.tgc.services.gotosocial.settings.account-domain
+              != config.tgc.services.gotosocial.settings.host
             )
           then
             {
-              "${config.modules.services.gotosocial.settings.account-domain}" = {
+              "${config.tgc.services.gotosocial.settings.account-domain}" = {
                 locations = {
                   "= /.well-known/host-meta".extraConfig =
-                    "return 301 https://${config.modules.services.gotosocial.settings.host}$request_uri;";
+                    "return 301 https://${config.tgc.services.gotosocial.settings.host}$request_uri;";
                   "= /.well-known/webfinger".extraConfig =
-                    "return 301 https://${config.modules.services.gotosocial.settings.host}$request_uri;";
+                    "return 301 https://${config.tgc.services.gotosocial.settings.host}$request_uri;";
                   "= /.well-known/nodeinfo".extraConfig =
-                    "return 301 https://${config.modules.services.gotosocial.settings.host}$request_uri;";
+                    "return 301 https://${config.tgc.services.gotosocial.settings.host}$request_uri;";
                 };
               };
             }
diff --git a/config/nixos/modules/websites/fedi.home.ctu.cx.nix b/config/nixos/modules/websites/fedi.home.ctu.cx.nix
@@ -1,7 +1,5 @@
 {
-  name,
   povSelf,
-  hostConfig,
   config,
   pkgs,
   lib,

@@ -11,7 +9,6 @@
 let
   inherit (lib) types;
   cfg = lib.getAttrFromPath povSelf config;
-  cfgWebsites = lib.getAttrFromPath (lib.remove name povSelf) config;
 
 in
 {

@@ -21,18 +18,10 @@ in
       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}." ];
+    dns.zones."ctu.cx".subdomains."fedi.home".CNAME = [ "${config.networking.fqdn}." ];
 
     sops.secrets = {
       "resticPasswords/gotosocial" = { };

@@ -40,76 +29,87 @@ in
 
     systemd.tmpfiles.settings.gotosocial = {
       "/var/lib/gotosocial/storage".d = {
-        user = config.modules.services.gotosocial.user;
-        group = config.modules.services.gotosocial.group;
+        user = config.tgc.services.gotosocial.user;
+        group = config.tgc.services.gotosocial.group;
         mode = "750";
         age = "-";
       };
     };
 
-    modules.services = {
-      resticBackup.paths = {
+    modules = {
+      filesystem.impermanence.system.dirs = [
+        {
+          directory = config.tgc.services.gotosocial.stateDir;
+          mode = "0755";
+          user = config.tgc.services.gotosocial.user;
+          group = config.tgc.services.gotosocial.group;
+        }
+      ];
+
+      services.resticBackup.paths = {
         gotosocial = {
           enable = true;
-          user = config.modules.services.gotosocial.user;
+          package = pkgs.tgc.gotosocial-unstable;
+          user = config.tgc.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)
+              config.tgc.services.gotosocial.settings.db-type == "sqlite"
+            ) config.tgc.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"
+              config.tgc.services.gotosocial.settings.storage-backend == "local"
+            ) config.tgc.services.gotosocial.settings.storage-local-base-path)
+            "${config.tgc.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'';
+          runBeforeBackup = ''${config.tgc.services.gotosocial.package}/bin/gotosocial --config-path /etc/gotosocial.yaml admin export --path ${config.tgc.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";
+    tgc.services.gotosocial = {
+      enable = true;
+      group = config.services.nginx.group;
+      settings = {
+        protocol = "https";
 
-          storage-backend = lib.mkDefault "local";
-          storage-local-base-path = "${config.modules.services.gotosocial.stateDir}/storage";
+        bind-address = "[::1]";
+        port = 8085;
 
-          host = "${cfg.subdomain}.${cfg.domain}";
-          account-domain = cfg.domain;
+        trusted-proxies = [
+          "::1/128"
+          "172.17.0.0/24"
+        ];
 
-          landing-page-user = "leah";
+        db-type = lib.mkDefault "sqlite";
+        db-address = lib.mkDefault "${config.tgc.services.gotosocial.stateDir}/db.sqlite";
 
-          accounts-allow-custom-css = true;
-          accounts-registration-open = false;
+        storage-backend = lib.mkDefault "local";
+        storage-local-base-path = "${config.tgc.services.gotosocial.stateDir}/storage";
 
-          instance-expose-peers = true;
-          instance-expose-suspended = true;
-          instance-expose-suspended-web = true;
+        host = "fedi.home.ctu.cx";
+        account-domain = "fedi.home.ctu.cx";
 
-          instance-languages = [
-            "de"
-            "en-us"
-          ];
+        landing-page-user = "leah";
 
-          media-local-max-size = "50MiB";
-          media-remote-max-size = "50MiB";
+        accounts-allow-custom-css = true;
+        accounts-registration-open = false;
 
-          media-remote-cache-days = 3;
-          media-cleanup-from = "01:00";
-        };
+        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";
       };
     };
 

@@ -119,18 +119,18 @@ in
       '';
       virtualHosts =
         {
-          "${config.modules.services.gotosocial.settings.host}" = {
+          "${config.tgc.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}";
+                proxyPass = "http://${toString config.tgc.services.gotosocial.settings.bind-address}:${toString config.tgc.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}";
+                proxyPass = "http://${toString config.tgc.services.gotosocial.settings.bind-address}:${toString config.tgc.services.gotosocial.settings.port}";
                 extraConfig = ''
                   proxy_cache gotosocial_ap_public_responses;
                   proxy_cache_background_update on;

@@ -143,7 +143,7 @@ in
               };
 
               "~ ^\/users\/(?:[a-z0-9_\.]+)\/main-key$" = {
-                proxyPass = "http://${toString config.modules.services.gotosocial.settings.bind-address}:${toString config.modules.services.gotosocial.settings.port}";
+                proxyPass = "http://${toString config.tgc.services.gotosocial.settings.bind-address}:${toString config.tgc.services.gotosocial.settings.port}";
                 extraConfig = ''
                   proxy_cache gotosocial_ap_public_responses;
                   proxy_cache_background_update on;

@@ -157,7 +157,7 @@ in
               };
 
               "/assets/".extraConfig = ''
-                alias ${config.modules.services.gotosocial.package}/share/web/assets/;
+                alias ${config.tgc.services.gotosocial.package}/share/web/assets/;
                 autoindex off;
                 expires max;
                 add_header Cache-Control "public, immutable";

@@ -168,19 +168,19 @@ in
         // (
           if
             (
-              config.modules.services.gotosocial.settings.account-domain
-              != config.modules.services.gotosocial.settings.host
+              config.tgc.services.gotosocial.settings.account-domain
+              != config.tgc.services.gotosocial.settings.host
             )
           then
             {
-              "${config.modules.services.gotosocial.settings.account-domain}" = {
+              "${config.tgc.services.gotosocial.settings.account-domain}" = {
                 locations = {
                   "= /.well-known/host-meta".extraConfig =
-                    "return 301 https://${config.modules.services.gotosocial.settings.host}$request_uri;";
+                    "return 301 https://${config.tgc.services.gotosocial.settings.host}$request_uri;";
                   "= /.well-known/webfinger".extraConfig =
-                    "return 301 https://${config.modules.services.gotosocial.settings.host}$request_uri;";
+                    "return 301 https://${config.tgc.services.gotosocial.settings.host}$request_uri;";
                   "= /.well-known/nodeinfo".extraConfig =
-                    "return 301 https://${config.modules.services.gotosocial.settings.host}$request_uri;";
+                    "return 301 https://${config.tgc.services.gotosocial.settings.host}$request_uri;";
                 };
               };
             }
diff --git a/config/nixos/modules/websites/gomuks.zaphyra.eu.nix b/config/nixos/modules/websites/gomuks.zaphyra.eu.nix
@@ -1,7 +1,5 @@
 {
-  name,
   povSelf,
-  hostConfig,
   config,
   pkgs,
   lib,

@@ -11,7 +9,6 @@
 let
   inherit (lib) types;
   cfg = lib.getAttrFromPath povSelf config;
-  cfgWebsites = lib.getAttrFromPath (lib.remove name povSelf) config;
 
 in
 {

@@ -48,9 +45,7 @@ in
 
       serviceConfig = {
         Type = "simple";
-        ExecStart = lib.getExe (pkgs.gomuks-web.override {
-          withGoolm = true;
-        });
+        ExecStart = lib.getExe pkgs.tgc.gomuks-web;
 
         DynamicUser = true;
         User  = "gomuks-web";
diff --git a/config/nixos/modules/websites/gts.zaphyra.eu.nix b/config/nixos/modules/websites/gts.zaphyra.eu.nix
@@ -1,7 +1,6 @@
 {
   name,
   povSelf,
-  hostConfig,
   config,
   pkgs,
   lib,

@@ -21,14 +20,6 @@ in
       type = types.bool;
       default = false;
     };
-    domain = {
-      type = types.str;
-      default = "zaphyra.eu";
-    };
-    subdomain = {
-      type = types.str;
-      default = "gts";
-    };
   };
 
   config = lib.mkIf cfg.enable {

@@ -39,9 +30,10 @@ in
       }
     ];
 
-    dns.zones."${cfg.domain}".subdomains."${cfg.subdomain}".CNAME = [ "${config.networking.fqdn}." ];
+    dns.zones."zaphyra.eu".subdomains."gts".CNAME = [ "${config.networking.fqdn}." ];
 
     systemd.services.gotosocial.after = [ "sops-install-secrets.service" ];
+
     sops.secrets = {
       "resticPasswords/gotosocial" = {
         owner = "gotosocial";

@@ -53,82 +45,93 @@ in
 
     systemd.tmpfiles.settings.gotosocial = {
       "/var/lib/gotosocial/storage".d = {
-        user = config.modules.services.gotosocial.user;
-        group = config.modules.services.gotosocial.group;
+        user = config.tgc.services.gotosocial.user;
+        group = config.tgc.services.gotosocial.group;
         mode = "750";
         age = "-";
       };
     };
 
-    modules.services = {
-      resticBackup.paths = {
+    modules = {
+      filesystem.impermanence.system.dirs = [
+        {
+          directory = config.tgc.services.gotosocial.stateDir;
+          mode = "0755";
+          user = config.tgc.services.gotosocial.user;
+          group = config.tgc.services.gotosocial.group;
+        }
+      ];
+
+      services.resticBackup.paths = {
         gotosocial = {
           enable = true;
-          user = config.modules.services.gotosocial.user;
+          user = config.tgc.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)
+              config.tgc.services.gotosocial.settings.db-type == "sqlite"
+            ) config.tgc.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"
+              config.tgc.services.gotosocial.settings.storage-backend == "local"
+            ) config.tgc.services.gotosocial.settings.storage-local-base-path)
+            "${config.tgc.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'';
+          runBeforeBackup = ''${config.tgc.services.gotosocial.package}/bin/gotosocial --config-path /etc/gotosocial.yaml admin export --path ${config.tgc.services.gotosocial.stateDir}/backup.json'';
         };
       };
-      gotosocial = {
-        enable = true;
-        group = config.services.nginx.group;
-        environmentFile = config.sops.secrets.gotosocialEnv.path;
-        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";
+    tgc.services.gotosocial = {
+      enable = true;
+      package = pkgs.tgc.gotosocial-unstable;
+      group = config.services.nginx.group;
+      environmentFile = config.sops.secrets.gotosocialEnv.path;
+      settings = {
+        protocol = "https";
 
-          storage-backend = lib.mkDefault "local";
-          storage-local-base-path = "${config.modules.services.gotosocial.stateDir}/storage";
+        bind-address = "[::1]";
+        port = 8085;
 
-          host = "${cfg.subdomain}.${cfg.domain}";
-          account-domain = cfg.domain;
+        trusted-proxies = [
+          "::1/128"
+          "172.17.0.0/24"
+        ];
 
-          landing-page-user = "katja";
+        db-type = "sqlite";
+        db-address = "${config.tgc.services.gotosocial.stateDir}/db.sqlite";
 
-          accounts-allow-custom-css = true;
-          accounts-registration-open = false;
+        storage-backend = "local";
+        storage-local-base-path = "${config.tgc.services.gotosocial.stateDir}/storage";
 
-          instance-expose-peers = true;
-          instance-expose-suspended = true;
-          instance-expose-suspended-web = true;
+        host = "gts.zaphyra.eu";
+        account-domain = "zaphyra.eu";
 
-          instance-languages = [
-            "de"
-            "en-us"
-          ];
+        landing-page-user = "katja";
 
-          media-local-max-size = "50MiB";
-          media-remote-max-size = "50MiB";
+        accounts-allow-custom-css = true;
+        accounts-registration-open = false;
 
-          media-remote-cache-days = 3;
-          media-cleanup-from = "01:00";
+        instance-expose-peers = true;
+        instance-expose-suspended = true;
+        instance-expose-suspended-web = true;
 
-          smtp-host = "morio.infra.zaphyra.eu";
-          smtp-port = 587;
-          smtp-username = "gts@zaphyra.eu";
-          smtp-from = "gts@zaphyra.eu";
-        };
+        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";
+
+        smtp-host = "morio.infra.zaphyra.eu";
+        smtp-port = 587;
+        smtp-username = "gts@zaphyra.eu";
+        smtp-from = "gts@zaphyra.eu";
       };
     };
 

@@ -138,20 +141,20 @@ in
       '';
       virtualHosts =
         {
-          "${config.modules.services.gotosocial.settings.host}" = {
+          "${config.tgc.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}";
+                proxyPass = "http://${toString config.tgc.services.gotosocial.settings.bind-address}:${toString config.tgc.services.gotosocial.settings.port}";
                 proxyWebsockets = true;
               };
 
               "/client/" = {
                 index = "index.html";
                 alias = "${
-                  pkgs.phanpy.override {
+                  pkgs.tgc.phanpy.override {
                     clientName = "zaphyra's fedi";
                     website = "https://gts.zaphyra.eu/client/";
                     defaultInstance = "gts.zaphyra.eu";

@@ -159,7 +162,7 @@ in
                 }/";
               };
               "~ /.well-known/(webfinger|host-meta)$" = {
-                proxyPass = "http://${toString config.modules.services.gotosocial.settings.bind-address}:${toString config.modules.services.gotosocial.settings.port}";
+                proxyPass = "http://${toString config.tgc.services.gotosocial.settings.bind-address}:${toString config.tgc.services.gotosocial.settings.port}";
                 extraConfig = ''
                   proxy_cache gotosocial_ap_public_responses;
                   proxy_cache_background_update on;

@@ -172,7 +175,7 @@ in
               };
 
               "~ ^\/users\/(?:[a-z0-9_\.]+)\/main-key$" = {
-                proxyPass = "http://${toString config.modules.services.gotosocial.settings.bind-address}:${toString config.modules.services.gotosocial.settings.port}";
+                proxyPass = "http://${toString config.tgc.services.gotosocial.settings.bind-address}:${toString config.tgc.services.gotosocial.settings.port}";
                 extraConfig = ''
                   proxy_cache gotosocial_ap_public_responses;
                   proxy_cache_background_update on;

@@ -186,7 +189,7 @@ in
               };
 
               "/assets/".extraConfig = ''
-                alias ${config.modules.services.gotosocial.package}/share/web/assets/;
+                alias ${config.tgc.services.gotosocial.package}/share/gotosocial/web/assets/;
                 autoindex off;
                 expires max;
                 add_header Cache-Control "public, immutable";

@@ -197,19 +200,19 @@ in
         // (
           if
             (
-              config.modules.services.gotosocial.settings.account-domain
-              != config.modules.services.gotosocial.settings.host
+              config.tgc.services.gotosocial.settings.account-domain
+              != config.tgc.services.gotosocial.settings.host
             )
           then
             {
-              "${config.modules.services.gotosocial.settings.account-domain}" = {
+              "${config.tgc.services.gotosocial.settings.account-domain}" = {
                 locations = {
                   "= /.well-known/host-meta".extraConfig =
-                    "return 301 https://${config.modules.services.gotosocial.settings.host}$request_uri;";
+                    "return 301 https://${config.tgc.services.gotosocial.settings.host}$request_uri;";
                   "= /.well-known/webfinger".extraConfig =
-                    "return 301 https://${config.modules.services.gotosocial.settings.host}$request_uri;";
+                    "return 301 https://${config.tgc.services.gotosocial.settings.host}$request_uri;";
                   "= /.well-known/nodeinfo".extraConfig =
-                    "return 301 https://${config.modules.services.gotosocial.settings.host}$request_uri;";
+                    "return 301 https://${config.tgc.services.gotosocial.settings.host}$request_uri;";
                 };
               };
             }
diff --git a/flake.nix b/flake.nix
@@ -53,15 +53,12 @@
 
       homeManagerModules = loadDir pathLoader ./config/home-manager;
 
-      overlays = (loadDir importLoader ./overlays) // {
-        nixpkgsUnstable = final: prev: { unstable = inputs.nixpkgsUnstable.legacyPackages.${prev.system}; };
+      overlays = {
         packages = final: prev: loadDir (path: path: final.callPackage path { }) ./packages;
       };
 
       nixpkgsOverlays = [
         inputs.self.overlays.packages
-        inputs.self.overlays.nixpkgsUnstable
-        inputs.self.overlays.tuigreet
         inputs.zaphyraWebsite.overlays.default
         inputs.stagit.overlays.default
         inputs.flauschehornSexy.overlays.default

@@ -71,6 +68,7 @@
         inputs.mqttWebUI.overlays.default
         inputs.airpodsctl.overlays.default
         inputs.tgcNUR.overlays.default
+        inputs.tgcNUR.overlays.nixpkgsUnstable
         inputs.tgcNUR.overlays.tuigreet
         (final: prev: { sherlock-launcher = inputs.sherlock.packages.${prev.system}.default; })
       ];
diff --git a/overlays/tuigreet.nix b/overlays/tuigreet.nix
@@ -1,20 +0,0 @@
-final: prev: {
-  greetd = prev.greetd // {
-    tuigreet = prev.greetd.tuigreet.overrideAttrs rec {
-      version = "0.10.0-unstable-2024-11-12";
-      useFetchCargoVendor = true;
-      # for some stupid reason `cargoHash` doesn't work in `overrideAttrs`, so we have to do it this way
-      cargoDeps = final.rustPlatform.fetchCargoVendor {
-        inherit src;
-        hash = "sha256-FrWDRsYhfq46wBm7F0Tifiw5oGXzSgwZC05ndNXcg8k=";
-      };
-      src = prev.fetchFromGitHub {
-        owner = "apognu";
-        repo = "tuigreet";
-        rev = "2aeca1b63dec977fc4e2ac6f97432386bedbc546";
-        sha256 = "sha256-6hVTU575tP+bPAUZlGhDwvBTVISyORC0wqljC7guZdA=";
-      };
-      doCheck = false;
-    };
-  };
-}
diff --git a/packages/adwaita-colors-icon-theme.nix b/packages/adwaita-colors-icon-theme.nix
@@ -1,41 +0,0 @@
-{
-  lib,
-  stdenvNoCC,
-  fetchFromGitHub,
-  gtk3,
-  xdg-utils,
-}:
-
-stdenvNoCC.mkDerivation rec {
-  pname = "adwaita-colors-icon-theme";
-  version = "2.3";
-
-  src = fetchFromGitHub {
-    owner = "dpejoh";
-    repo = "Adwaita-colors";
-    rev = "v${version}";
-    hash = "sha256-q7qvE55vtd8K0T+VQKJ0Qa/qIPToRh3xU1wLjyW68nQ=";
-  };
-
-  nativeBuildInputs = [
-    gtk3
-    xdg-utils
-  ];
-
-  installPhase = ''
-    runHook preInstall
-
-    install -d $out/share/icons
-    cp -r Adwaita-* $out/share/icons/
-    gtk-update-icon-cache -f -t $out/share/icons/Adwaita* && xdg-desktop-menu forceupdate
-
-    runHook postInstall
-  '';
-
-  meta = with lib; {
-    description = "Adwaita Colors customizes Adwaita icons to match your GNOME theme's accent color, providing a cohesive, personalized look.";
-    homepage = "https://github.com/dpejoh/Adwaita-colors";
-    license = with licenses; [ gpl3Only ];
-    platforms = platforms.linux;
-  };
-}
diff --git a/packages/chaosctl/chaosctl.fish b/packages/chaosctl/chaosctl.fish
@@ -1,65 +0,0 @@
-# GLOBALS
-set CMD "$argv[1]"
-set CMDS beamer door help tv
-
-function error
-    echo $argv[2..] 1>&2
-    return $argv[1]
-end
-
-set _descr_beamer "Control the beamer in the lounge"
-set _usage_beamer "<on|off>"
-function cmd_beamer
-    switch $argv[1]
-        case on
-            ssh chaos@lounge.cccda.de beamer-on
-        case off
-            ssh chaos@lounge.cccda.de beamer-off
-        case "*"
-            error 1 "$(cmd_help beamer)"
-    end
-end
-
-set _descr_door "Control the door"
-function cmd_door
-    ssh door@door.cccda.de $argv
-end
-
-set _descr_help "Display this message"
-function cmd_help
-    set cmd "$argv[1]"
-    if [ "$cmd" != "" ]
-        echo "\
-$(eval echo \$_descr_$cmd)
-
-Usage:
-    chaosctl $cmd $(eval echo \$_usage_$cmd)"
-    else
-        echo "\
-The chaosctl utility
-
-Usage:
-    chaosctl <command>
-
-COMMANDS"
-        for cmd in $CMDS
-            echo -e "    $cmd\t$(eval echo \$_descr_$cmd)"
-        end
-    end
-end
-
-set _descr_tv "\tControl the TV in the kitchen"
-function cmd_tv
-    ssh chaos@kitchen.cccda.de tv $argv
-end
-
-if [ "cmd_$CMD" = cmd_ ]
-    error 1 "$(cmd_help)"
-    exit $status
-end
-
-if type -q "cmd_$CMD"
-    cmd_$CMD $argv[2..]
-else
-    error 127 "No such subcommand '$CMD'"
-end
diff --git a/packages/chaosctl/default.nix b/packages/chaosctl/default.nix
@@ -1,5 +0,0 @@
-{
-  writers,
-  ...
-}:
-writers.writeFishBin "chaosctl" ./chaosctl.fish
diff --git a/packages/gotosocial/default.nix b/packages/gotosocial/default.nix
@@ -1,99 +0,0 @@
-{
-  applyPatches,
-  fetchgit,
-  mkYarnPackage,
-  buildGo124Module,
-  lib,
-  makeWrapper,
-  installShellFiles,
-  ...
-}:
-
-buildGo124Module rec {
-  pname = "gotosocial";
-  version = "0.20.0-${builtins.substring 0 6 rev}";
-  rev = "b6ff55662e0281c0d6e111f9307625ef695df2fa";
-  hash = "sha256-btdStdOlIWIFzTQYFzinH5N/U71LETkg8phY7p+eDtw=";
-
-  src = applyPatches {
-    src = fetchgit {
-      url = "https://codeberg.org/superseriousbusiness/gotosocial/";
-      inherit rev hash;
-    };
-    patches = [ ];
-  };
-
-  frontend-assets = mkYarnPackage {
-    name = "${pname}_${version}-frontend-assets";
-    inherit src version;
-
-    packageJSON = "${src}/web/source/package.json";
-    yarnLock = "${src}/web/source/yarn.lock";
-
-    configurePhase = ''
-      cp -r $node_modules node_modules
-      chmod +w -R node_modules
-    '';
-
-    buildPhase = ''
-      mkdir -p ./web/source ./web/assets
-
-      cp -r $src/web/source/. ./web/source
-      cp -r $src/web/assets/. ./web/assets
-
-      export NODE_OPTIONS=--openssl-legacy-provider
-      node ./node_modules/ts-patch/bin/ts-patch.js install
-      yarn --offline --cwd ./web/source build
-    '';
-
-    distPhase = "true";
-    installPhase = "cp -r ./web/assets $out";
-
-    meta.license = lib.licenses.agpl3Only;
-  };
-
-  ldflags = [
-    "-s"
-    "-w"
-    "-extldflags '-static'"
-    "-X 'main.Commit=${rev}'"
-    "-X 'main.Version=${version}'"
-  ];
-  tags = [
-    "netgo"
-    "osusergo"
-    "static_build"
-  ];
-
-  vendorHash = null;
-
-  nativeBuildInputs = [ installShellFiles ];
-  buildInputs = [ makeWrapper ];
-
-  doCheck = false;
-
-  installCheckPhase = ''
-    runHook preCheck
-    $out/bin/gotosocial --help
-    runHook postCheck
-  '';
-
-  postInstall = ''
-    mkdir -p $out/share/web/assets
-
-    cp -r  ./web/template                  $out/share/web/
-    cp -rf ${frontend-assets}/. $out/share/web/assets
-
-    installShellCompletion --cmd gotosocial \
-      --bash <($out/bin/gotosocial completion bash) \
-      --fish <($out/bin/gotosocial completion fish) \
-      --zsh <($out/bin/gotosocial completion zsh)
-  '';
-
-  meta = with lib; {
-    description = "An ActivityPub social network server, written in Golang.";
-    homepage = "https://github.com/superseriousbusiness/gotosocial";
-    license = licenses.agpl3Only;
-  };
-
-}
diff --git a/packages/mautrix-telegramgo.nix b/packages/mautrix-telegramgo.nix
@@ -1,48 +0,0 @@
-{
-  lib,
-  stdenv,
-  buildGoModule,
-  fetchFromGitHub,
-  olm,
-  versionCheckHook,
-  # This option enables the use of an experimental pure-Go implementation of
-  # the Olm protocol instead of libolm for end-to-end encryption. Using goolm
-  # is not recommended by the mautrix developers, but they are interested in
-  # people trying it out in non-production-critical environments and reporting
-  # any issues they run into.
-  withGoolm ? true,
-}:
-
-let
-  cppStdLib = if stdenv.hostPlatform.isDarwin then "-lc++" else "-lstdc++";
-
-in
-buildGoModule rec {
-  pname = "mautrix-telegramgo";
-  rev = "ea4626107c56799ad3ca503e63450823a7f36546";
-  version = "0.0.0-${builtins.substring 0 6 rev}";
-  hash = "sha256-wV6wH60+qF+A/KHS9BDQbSG0pD2yRedqbqH1ea0gCKU=";
-
-  src = fetchFromGitHub {
-    owner = "mautrix";
-    repo = "telegramgo";
-    inherit rev hash;
-  };
-
-  buildInputs = (lib.optional (!withGoolm) olm) ++ (lib.optional withGoolm stdenv.cc.cc.lib);
-
-  CGO_LDFLAGS = lib.optional withGoolm [ cppStdLib ];
-
-  tags = lib.optional withGoolm "goolm";
-
-  doCheck = false;
-
-  vendorHash = "sha256-3gJwR4gmkoOKQfiWe3pI04638wgJjyissAND5XbBGHM=";
-
-  meta = with lib; {
-    homepage = "https://github.com/mautrix/telegramgo";
-    description = "Go rewrite of mautrix-telegram";
-    license = licenses.agpl3Plus;
-    mainProgram = "mautrix-telegram";
-  };
-}
diff --git a/packages/phanpy.nix b/packages/phanpy.nix
@@ -1,46 +0,0 @@
-{
-  lib,
-  fetchFromGitHub,
-  buildNpmPackage,
-  clientName ? "Phanpy",
-  website ? "https://phanpy.social",
-  defaultInstance ? "",
-  defaultInstanceRegistrationUrl ? "",
-  defaultLang ? "en",
-  ...
-}:
-
-buildNpmPackage (finalAttrs: {
-  pname = "phanpy";
-  version = "2025.04.28.5849b4d";
-
-  src = fetchFromGitHub {
-    owner = "cheeaun";
-    repo = "phanpy";
-    tag = finalAttrs.version;
-    hash = "sha256-Mp8ckYktjhQwuxirlMntzaA2IbExGaPPEj4IAKibvEQ=";
-  };
-
-  npmDepsHash = "sha256-02comyhYcY7Q71Cx9RCWIeKz1RwNcJPtSR5/EB2v+jU=";
-
-  NODE_OPTIONS = "--openssl-legacy-provider";
-
-  env = {
-    PHANPY_CLIENT_NAME = clientName;
-    PHANPY_WEBSITE = website;
-    PHANPY_DEFAULT_INSTANCE = defaultInstance;
-    PHANPY_DEFAULT_INSTANCE_REGISTRATION_URL = defaultInstanceRegistrationUrl;
-    PHANPY_DEFAULT_LANG = defaultLang;
-  };
-
-  installPhase = ''
-    cp -r ./dist $out
-  '';
-
-  meta = {
-    description = "A minimalistic opinionated Mastodon web client ";
-    homepage = "https://github.com/cheeaun/phanpy";
-    license = lib.licenses.mit;
-    maintainers = with lib.maintainers; [ ctucx ];
-  };
-})
diff --git a/packages/shaderbg.nix b/packages/shaderbg.nix
@@ -1,47 +0,0 @@
-
-{
-  lib,
-  fetchFromSourcehut,
-  stdenv,
-  meson,
-  cmake,
-  ninja,
-  pkg-config,
-  libGL,
-  wayland,
-  wayland-scanner,
-  ...
-}:
-
-stdenv.mkDerivation (finalAttrs: {
-  pname = "shaderbg";
-  version = "0.0.0-unstable-2023-03-16";
-  rev = "af9827d20bfe1956dd88fb2202b38ed0de705305";
-
-  buildInputs = [
-    meson
-    cmake
-    ninja
-    pkg-config
-    libGL
-    wayland
-    wayland-scanner
-  ];
-
-  src = fetchFromSourcehut {
-    owner = "~mstoeckl";
-    repo = finalAttrs.pname;
-    rev = finalAttrs.rev;
-    hash = "sha256-/HtbS+vn69oEDVP4HDBvnmpkGRLz62j8lCZx+plrUeI=";
-  };
-
-  meta = {
-    description = "A live wallpaper program for Sway and other compositors with wlr-layer-shell support";
-    homepage = "https://git.sr.ht/~mstoeckl/shaderbg";
-    license = lib.licenses.gpl3;
-    maintainers = [];
-    platforms = lib.platforms.linux;
-    mainProgram = "shaderbg";
-  };
-
-})
diff --git a/packages/sointu.nix b/packages/sointu.nix
@@ -1,64 +0,0 @@
-{
-  fetchFromGitHub,
-  buildGoModule,
-  pkg-config,
-  libxkbcommon,
-  alsa-lib,
-  wayland,
-  vulkan-headers,
-  xorg,
-  libGL,
-  lib,
-  makeWrapper,
-  installShellFiles,
-  ...
-}:
-
-buildGoModule (finalAttrs: {
-  pname = "sointu";
-  version = "unstable-2025-07-24";
-  rev = "fe0106bb604f6f898091c6c7a042b97b9e2b2c48";
-
-  src = fetchFromGitHub {
-    owner = "vsariola";
-    repo = finalAttrs.pname;
-    rev = finalAttrs.rev;
-    hash = "sha256-N1Z9uccQXnrsLtyvUdb7IwPsDzziLeu2UYtndwWTQXA=";
-  };
-
-  vendorHash = "sha256-gLDLKqu6k7/nwv6xHUE6MIYrbQFfVFAuUiMbLptcE5k=";
-  proxyVendor = true;
-
-  subPackages = [
-    "cmd/sointu-compile"
-    "cmd/sointu-play"
-    "cmd/sointu-track"
-  ];
-
-  nativeBuildInputs = [
-    pkg-config
-    makeWrapper
-  ];
-
-  buildInputs = [
-    libxkbcommon
-    alsa-lib
-    wayland
-    libGL
-    vulkan-headers
-    xorg.libX11
-    xorg.libXcursor
-    xorg.libXfixes
-  ];
-
-  env.CGO_ENABLED = true;
-
-  doCheck = false;
-
-  meta = with lib; {
-    description = "Fork of 4klang that can target 386, amd64 and WebAssembly. Tools run on Windows, Mac & Linux";
-    homepage = "https://github.com/vsariola/sointu";
-    license = licenses.mit;
-  };
-
-})
diff --git a/packages/wlsbg.nix b/packages/wlsbg.nix
@@ -1,59 +0,0 @@
-
-{
-  lib,
-  fetchFromGitHub,
-  stdenv,
-  meson,
-  cmake,
-  ninja,
-  scdoc,
-  git,
-  pkg-config,
-  wayland,
-  wayland-protocols,
-  wayland-scanner,
-  libGL,
-  mpv,
-  fftwFloat,
-  ...
-}:
-
-stdenv.mkDerivation (finalAttrs: {
-  pname = "wlsbg";
-  version = "3.3.7";
-
-  nativeBuildInputs = [
-    meson
-    ninja
-    pkg-config
-    cmake
-    scdoc
-    git
-  ];
-
-  buildInputs = [
-    wayland
-    wayland-protocols
-    wayland-scanner
-    libGL
-    mpv
-    fftwFloat
-  ];
-
-  src = fetchFromGitHub {
-    owner = "Sublimeful";
-    repo = finalAttrs.pname;
-    rev = "v${finalAttrs.version}";
-    hash = "sha256-e0eOLsfU4wrz8Ck/iWwSnimTSYICmN/3vKeObmSE6zA=";
-  };
-
-  meta = {
-    description = "Wallpaper tool with shader support for Wayland compositors";
-    homepage = "https://github.com/Sublimeful/wlsbg";
-    license = lib.licenses.mit;
-    maintainers = [];
-    platforms = lib.platforms.linux;
-    mainProgram = "wlsbg";
-  };
-
-})