1 { config, pkgs, lib, ... }:
3 cfg = config.services.pufferpanel;
6 options.services.pufferpanel = {
7 enable = lib.mkOption {
11 Whether to enable PufferPanel game management server.
13 Note that [PufferPanel templates] and binaries downloaded by PufferPanel
14 expect [FHS environment]. It is possible to set {option}`package` option
15 to use PufferPanel wrapper with FHS environment. For example, to use
16 `Download Game from Steam` and `Download Java` template operations:
19 services.pufferpanel = {
21 extraPackages = with pkgs; [ bash curl gawk gnutar gzip ];
22 package = pkgs.buildFHSEnv {
23 name = "pufferpanel-fhs";
24 runScript = lib.getExe pkgs.pufferpanel;
25 targetPkgs = pkgs': with pkgs'; [ icu openssl zlib ];
31 [PufferPanel templates]: https://github.com/PufferPanel/templates
32 [FHS environment]: https://wikipedia.org/wiki/Filesystem_Hierarchy_Standard
36 package = lib.mkPackageOption pkgs "pufferpanel" { };
38 extraGroups = lib.mkOption {
39 type = lib.types.listOf lib.types.str;
41 example = [ "podman" ];
43 Additional groups for the systemd service.
47 extraPackages = lib.mkOption {
48 type = lib.types.listOf lib.types.package;
50 example = lib.literalExpression "[ pkgs.jre ]";
52 Packages to add to the PATH environment variable. Both the {file}`bin`
53 and {file}`sbin` subdirectories of each package are added.
57 environment = lib.mkOption {
58 type = lib.types.attrsOf lib.types.str;
60 example = lib.literalExpression ''
62 PUFFER_WEB_HOST = ":8080";
63 PUFFER_DAEMON_SFTP_HOST = ":5657";
64 PUFFER_DAEMON_CONSOLE_BUFFER = "1000";
65 PUFFER_DAEMON_CONSOLE_FORWARD = "true";
66 PUFFER_PANEL_REGISTRATIONENABLED = "false";
70 Environment variables to set for the service. Secrets should be
71 specified using {option}`environmentFile`.
73 Refer to the [PufferPanel source code][] for the list of available
74 configuration options. Variable name is an upper-cased configuration
75 entry name with underscores instead of dots, prefixed with `PUFFER_`.
76 For example, `panel.settings.companyName` entry can be set using
77 {env}`PUFFER_PANEL_SETTINGS_COMPANYNAME`.
79 When running with panel enabled (configured with `PUFFER_PANEL_ENABLE`
80 environment variable), it is recommended disable registration using
81 `PUFFER_PANEL_REGISTRATIONENABLED` environment variable (registration is
82 enabled by default). To create the initial administrator user, run
83 {command}`pufferpanel --workDir /var/lib/pufferpanel user add --admin`.
85 Some options override corresponding settings set via web interface (e.g.
86 `PUFFER_PANEL_REGISTRATIONENABLED`). Those options can be temporarily
87 toggled or set in settings but do not persist between restarts.
89 [PufferPanel source code]: https://github.com/PufferPanel/PufferPanel/blob/master/config/entries.go
93 environmentFile = lib.mkOption {
94 type = lib.types.nullOr lib.types.path;
97 File to load environment variables from. Loaded variables override
98 values set in {option}`environment`.
103 config = lib.mkIf cfg.enable {
104 systemd.services.pufferpanel = {
105 description = "PufferPanel game management server";
106 wantedBy = [ "multi-user.target" ];
107 after = [ "network.target" ];
109 path = cfg.extraPackages;
110 environment = cfg.environment;
112 # Note that we export environment variables for service directories if the
113 # value is not set. An empty environment variable is considered to be set.
115 # export PUFFER_LOGS=${PUFFER_LOGS-$LOGS_DIRECTORY}
116 # would set PUFFER_LOGS to $LOGS_DIRECTORY if PUFFER_LOGS environment
117 # variable is not defined.
119 ${lib.concatLines (lib.mapAttrsToList (name: value: ''
120 export ${name}="''${${name}-${value}}"
122 PUFFER_LOGS = "$LOGS_DIRECTORY";
123 PUFFER_DAEMON_DATA_CACHE = "$CACHE_DIRECTORY";
124 PUFFER_DAEMON_DATA_SERVERS = "$STATE_DIRECTORY/servers";
125 PUFFER_DAEMON_DATA_BINARIES = "$STATE_DIRECTORY/binaries";
127 exec ${lib.getExe cfg.package} run --workDir "$STATE_DIRECTORY"
136 SupplementaryGroups = cfg.extraGroups;
138 StateDirectory = "pufferpanel";
139 StateDirectoryMode = "0700";
140 CacheDirectory = "pufferpanel";
141 CacheDirectoryMode = "0700";
142 LogsDirectory = "pufferpanel";
143 LogsDirectoryMode = "0700";
145 EnvironmentFile = cfg.environmentFile;
147 # Command "pufferpanel shutdown --pid $MAINPID" sends SIGTERM (code 15)
148 # to the main process and waits for termination. This is essentially
149 # KillMode=mixed we are using here. See
150 # https://freedesktop.org/software/systemd/man/systemd.kill.html#KillMode=
155 ProtectProc = "invisible";
157 ProtectHostname = true;
158 ProtectControlGroups = true;
159 ProtectKernelLogs = true;
160 ProtectKernelModules = true;
161 ProtectKernelTunables = true;
163 PrivateDevices = true;
164 RestrictRealtime = true;
165 RestrictNamespaces = [ "user" "mnt" ]; # allow buildFHSEnv
166 RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ];
167 LockPersonality = true;
168 DeviceAllow = [ "" ];
169 DevicePolicy = "closed";
170 CapabilityBoundingSet = [ "" ];
175 meta.maintainers = [ lib.maintainers.tie ];