From 7e909dbc21e5d65289b6ff6e920450f35abe5b94 Mon Sep 17 00:00:00 2001 From: Joakim Repomaa Date: Wed, 7 Jan 2026 13:10:15 +0200 Subject: [PATCH] use rpi imager from unstable --- home/common/default.nix | 2 +- modules/services/sillytavern.nix | 189 +++++++++++++++++++++++++++++++ 2 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 modules/services/sillytavern.nix diff --git a/home/common/default.nix b/home/common/default.nix index a18ee48..f6a4060 100644 --- a/home/common/default.nix +++ b/home/common/default.nix @@ -59,7 +59,7 @@ (writeShellScriptBin "fd" '' ${fd}/bin/fd -H "$@" '') - rpi-imager + pkgs-unstable.rpi-imager picocom imagemagick ghostscript diff --git a/modules/services/sillytavern.nix b/modules/services/sillytavern.nix new file mode 100644 index 0000000..09b1dfb --- /dev/null +++ b/modules/services/sillytavern.nix @@ -0,0 +1,189 @@ +{ + config, + lib, + pkgs-unstable, + ... +}: +let + cfg = config.services.sillytavern; + fqdn = "${cfg.subdomain}.${config.networking.domain}"; + defaultUser = "sillytavern"; + defaultGroup = "sillytavern"; +in +{ + options.services.sillytavern = { + enable = lib.mkEnableOption "sillytavern"; + + subdomain = lib.mkOption { + type = lib.types.str; + default = "sillytavern"; + }; + + user = lib.mkOption { + type = lib.types.str; + default = defaultUser; + description = '' + User account under which the web-application run. + ''; + }; + + group = lib.mkOption { + type = lib.types.str; + default = defaultGroup; + description = '' + Group account under which the web-application run. + ''; + }; + + package = lib.mkOption { + type = lib.types.package; + default = pkgs-unstable.sillytavern; + description = '' + SillyTavern package to use. + ''; + }; + + configFile = lib.mkOption { + type = lib.types.path; + default = "${pkgs-unstable.sillytavern}/lib/node_modules/sillytavern/config.yaml"; + defaultText = lib.literalExpression "\${pkgs.sillytavern}/lib/node_modules/sillytavern/config.yaml"; + description = '' + Path to the SillyTavern configuration file. + ''; + }; + + port = lib.mkOption { + type = lib.types.nullOr lib.types.port; + default = null; + example = 8045; + description = '' + Port on which SillyTavern will listen. + ''; + }; + + listenAddressIPv4 = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + example = "127.0.0.1"; + description = '' + Specific IPv4 address to listen to. + ''; + }; + + listenAddressIPv6 = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + example = "::1"; + description = '' + Specific IPv6 address to listen to. + ''; + }; + + listen = lib.mkOption { + type = lib.types.nullOr lib.types.bool; + default = null; + example = true; + description = '' + Whether to listen on all network interfaces. + ''; + }; + + whitelist = lib.mkOption { + type = lib.types.nullOr lib.types.bool; + default = null; + example = true; + description = '' + Enables whitelist mode. + ''; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.services.sillytavern = { + description = "Silly Tavern"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + # required by sillytavern's extension manager + path = [ pkgs-unstable.git ]; + environment.XDG_DATA_HOME = "%S"; + serviceConfig = { + Type = "simple"; + ExecStart = + let + f = x: name: lib.optional (x != null) "--${name}=${builtins.toString x}"; + in + lib.concatStringsSep " " ( + [ + "${lib.getExe cfg.package}" + ] + ++ f cfg.port "port" + ++ f cfg.listen "listen" + ++ f cfg.listenAddressIPv4 "listenAddressIPv4" + ++ f cfg.listenAddressIPv6 "listenAddressIPv6" + ++ f cfg.whitelist "whitelist" + ); + User = cfg.user; + Group = cfg.group; + Restart = "always"; + StateDirectory = "SillyTavern"; + BindPaths = [ + "%S/SillyTavern/extensions:${cfg.package}/lib/node_modules/sillytavern/public/scripts/extensions/third-party" + ]; + + # Security hardening + CapabilityBoundingSet = [ "" ]; + LockPersonality = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateTmp = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + ProtectSystem = "strict"; + }; + }; + + users.users.${cfg.user} = lib.mkIf (cfg.user == defaultUser) { + description = "sillytavern service user"; + isSystemUser = true; + inherit (cfg) group; + }; + + users.groups.${cfg.group} = lib.mkIf (cfg.group == defaultGroup) { }; + + systemd.tmpfiles.settings.sillytavern = { + "/var/lib/SillyTavern/data".d = { + mode = "0700"; + inherit (cfg) user group; + }; + "/var/lib/SillyTavern/extensions".d = { + mode = "0700"; + inherit (cfg) user group; + }; + "/var/lib/SillyTavern/config.yaml"."L+" = { + mode = "0600"; + argument = cfg.configFile; + inherit (cfg) user group; + }; + }; + + services.webserver = { + enable = lib.mkDefault true; + vHosts.${fqdn} = { + proxyBuffering = false; + locations."/" = { + proxyPort = cfg.port; + extraConfig = '' + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + ''; + }; + }; + }; + }; +}