nixos/sillytavern: add it (#418452)

Sandro 5d8e397c 1bb8085e

Changed files
+173
nixos
doc
manual
release-notes
modules
services
web-apps
+2
nixos/doc/manual/release-notes/rl-2511.section.md
···
- [fw-fanctrl](https://github.com/TamtamHero/fw-fanctrl), a simple systemd service to better control Framework Laptop's fan(s). Available as [hardware.fw-fanctrl](#opt-hardware.fw-fanctrl.enable).
+
- [SillyTavern](https://sillytavern.app/), LLM Frontend for Power Users. Available as [services.sillytavern](#opt-services.sillytavern.enable).
+
- [mautrix-discord](https://github.com/mautrix/discord), a Matrix-Discord puppeting/relay bridge. Available as [services.mautrix-discord](#opt-services.mautrix-discord.enable).
- [Timekpr-nExT](https://mjasnik.gitlab.io/timekpr-next/), a time managing application that helps optimizing time spent at computer for your subordinates, children or even for yourself. Available as [](#opt-services.timekpr.enable).
+1
nixos/modules/module-list.nix
···
./services/web-apps/sftpgo.nix
./services/web-apps/sharkey.nix
./services/web-apps/shiori.nix
+
./services/web-apps/sillytavern.nix
./services/web-apps/silverbullet.nix
./services/web-apps/simplesamlphp.nix
./services/web-apps/slskd.nix
+170
nixos/modules/services/web-apps/sillytavern.nix
···
+
{
+
config,
+
lib,
+
pkgs,
+
...
+
}:
+
+
let
+
cfg = config.services.sillytavern;
+
defaultUser = "sillytavern";
+
defaultGroup = "sillytavern";
+
in
+
{
+
meta.maintainers = [
+
lib.maintainers.wrvsrx
+
lib.maintainers.A1ca7raz
+
];
+
+
options = {
+
services.sillytavern = {
+
enable = lib.mkEnableOption "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.mkPackageOption pkgs "sillytavern" { };
+
+
configFile = lib.mkOption {
+
type = lib.types.path;
+
default = "${pkgs.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.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 pkgs.sillytavern}"
+
]
+
++ 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:${pkgs.sillytavern}/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;
+
};
+
};
+
};
+
}