From b1a8ea125cf8617bca38d35bd41eeb6596022ca6 Mon Sep 17 00:00:00 2001 From: kalmenn Date: Mon, 7 Jul 2025 13:52:45 +0200 Subject: [PATCH] testing --- .gitignore | 1 + flake.nix | 12 ++- modules/pterodactyl.nix | 209 ++++++++++++++++++++++++++++----------- packages/php.nix | 10 +- packages/pterodactyl.nix | 21 ++-- packages/wings.nix | 2 +- 6 files changed, 182 insertions(+), 73 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c4a847d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/result diff --git a/flake.nix b/flake.nix index b74252b..093cd33 100644 --- a/flake.nix +++ b/flake.nix @@ -11,9 +11,13 @@ ); packages = nixpkgs.lib.genAttrs [ "x86_64-linux" ] ( - system: nixpkgs.lib.genAttrs [ "pterodactyl" "php" "wings" ] ( - package: import ./packages/${package}.nix { pkgs = import nixpkgs { inherit system; }; }; - ) - }); + system: let + pkgs = import nixpkgs { inherit system; }; + in rec { + php = import ./packages/php.nix { inherit pkgs; }; + pterodactyl = import ./packages/pterodactyl.nix { inherit pkgs php; }; + wings = import ./packages/wings.nix { inherit pkgs; }; + } + ); }; } diff --git a/modules/pterodactyl.nix b/modules/pterodactyl.nix index 7dfbc1c..eff6a8e 100644 --- a/modules/pterodactyl.nix +++ b/modules/pterodactyl.nix @@ -2,20 +2,36 @@ { lib, config, pkgs, ... }: let - cfg = config.services.pterodactyl; - - flakePkgs = flake.outputs.packages.${pkgs.system}; + thisConfig = config.services.pterodactyl; defaultUser = "pterodactyl"; in { options.services.pterodactyl = { enable = lib.mkEnableOption "Enable the pterodacytl game server panel"; - proxy = { - enable = lib.mkEnableOption "Automatically configure Nginx to serve the panel"; - serverName = lib.mkOption { + pkg = lib.mkOption { + type = lib.types.package; + description = "The package in which to source the php files used by pterodactyl"; + default = flake.outputs.packages.${pkgs.system}.pterodactyl; + }; + + dataDir = lib.mkOption { + type = lib.types.str; + description = "The directory in which to store stateful data"; + default = "/data/services/pterodactyl"; + }; + + server = { + enable = lib.mkEnableOption '' + Automatically configure Nginx to serve the panel + + If you need more control over the nginx proxy, for now you must leave this option disabled + and write your own nginx configuration. Feel free to copy ours as a starting point. + ''; + + name = lib.mkOption { type = lib.types.str; - description = "The canonical domain on which the panel will be hosted"; + description = "The canonical domain name on which the panel will be hosted"; default = "localhost"; example = "pterodactyl.example.com"; }; @@ -27,27 +43,46 @@ in { }; }; - user = lib.mkOption { - type = lib.types.str; - description = '' - The user that owns the files managed by the panel. - If you change this, make sure their files are accessible by your www user - (probably "nginx"). - ''; - default = defaultUser; - example = defaultUser; - }; + php = { + socket = lib.mkOption { + type = lib.types.path; + description = "The location of the unix socket used by php-fpm"; + default = config.services.phpfpm.pools.pterodactyl.socket; + }; - pkg = lib.mkOption { - type = lib.types.package; - description = "The package in which to source the php files used by pterodactyl"; - default = flakePkgs.pterodactyl; - }; + user = lib.mkOption { + type = lib.types.str; + description = '' + The user that the php-fpm processes will run under. See also the `group` option. - dataDir = lib.mkOption { - type = lib.types.str; - description = "The directory in which to store stateful data"; - default = "/var/lib/pterodactyl"; + If you change this, make sure the unix socket is accessible by your www user + (probably "nginx"). + ''; + default = defaultUser; + }; + + group = lib.mkOption { + type = lib.types.str; + description = '' + The group that the php-fpm processes will run under. See also the `user` option. + + If you change this, make sure the unix socket is accessible by your www user + (probably "nginx"). + ''; + default = defaultUser; + }; + + root = lib.mkOption { + type = lib.types.path; + description = "The main application directory"; + default = "/srv/pterodactyl"; + }; + + pkg = lib.mkOption { + type = lib.types.package; + description = "The php package to use"; + default = flake.outputs.packages.${pkgs.system}.php; + }; }; redis = { @@ -67,29 +102,37 @@ in { }; }; - config = lib.mkIf cfg.enable { - users = lib.mkIf (cfg.user == defaultUser) { - users.${cfg.user} = { - isSystemUser = true; - createHome = true; - home = cfg.dataDir; - group = cfg.user; + config = lib.mkIf thisConfig.enable { + users = { + users = { + ${thisConfig.php.user} = lib.mkIf (thisConfig.php.user == defaultUser) { + isSystemUser = true; + createHome = true; + home = "/var/lib/pterodactyl"; + group = thisConfig.php.group; + }; + + ${config.services.nginx.user} = lib.mkIf (thisConfig.php.group == defaultUser) { + extraGroups = [ thisConfig.php.group ]; + }; }; - groups.${cfg.user} = { }; - - users.${config.services.nginx.user}.extraGroups = [ cfg.user ]; + groups = { + ${thisConfig.php.group} = lib.mkIf (thisConfig.php.group == defaultUser) {}; + }; }; - services.redis.servers.${cfg.redis.name} = lib.mkIf cfg.redis.configureLocally { + services.redis.servers.${thisConfig.redis.name} = lib.mkIf thisConfig.redis.configureLocally { enable = true; - port = cfg.redis.port; + port = thisConfig.redis.port; }; - services.nginx = lib.mkIf cfg.proxy.enable { + services.nginx = lib.mkIf thisConfig.server.enable { enable = true; - virtualHosts."${cfg.serverName}" = { + virtualHosts."pterodactyl" = { + serverName = thisConfig.server.name; + root = "${config.services.pterodactyl.pkg}/public"; extraConfig = '' @@ -101,7 +144,7 @@ in { include ${pkgs.nginx}/conf/fastcgi_params; fastcgi_split_path_info ^(.+\.php)(/.+)$; - fastcgi_pass unix:${config.services.phpfpm.pools.pterodactyl.socket}; + fastcgi_pass unix:${thisConfig.php.socket}; fastcgi_index index.php; @@ -127,7 +170,7 @@ in { }; services.phpfpm.pools.pterodactyl = { - user = cfg.user; + user = thisConfig.php.user; settings = { "listen.owner" = config.services.nginx.user; "pm" = "dynamic"; @@ -145,21 +188,75 @@ in { }; }; - systemd.services.pteroq = { - enable = true; - description = "Pterodactyl Queue Worker"; - after = [ "redis-${cfg.redis.name}.service" ]; - unitConfig = { StartLimitInterval = 180; }; - serviceConfig = { - User = cfg.user; - Group = cfg.user; - Restart = "always"; - ExecStart = - "${flakePkgs.php}/bin/php ${cfg.pkg}/artisan queue:work --queue=high,standard,low --sleep=3 --tries=3"; - StartLimitBurst = 30; - RestartSec = "5s"; + systemd = { + tmpfiles.settings."10-pterodactyl" = lib.mkIf thisConfig.php.manageHome (let + user = thisConfig.php.user; + group = thisConfig.php.group; + in { + "${thisConfig.dataDir}/cache" = { "d" = { inherit group user; mode = "750"; }; }; + "${thisConfig.dataDir}/storage" = { "d" = { inherit group user; mode = "750"; }; }; + "${thisConfig.php.root}" = { "d" = { inherit group user; mode = "750"; }; }; + }); + + services = { + pterodactyl-setup = { + description = "Setup the necessary files for the pterodactyl panel to work"; + + before = [ "pteroq.service" ] + ++ (if thisConfig.server.enable then [ "nginx.service" ] else []); + wantedBy = [ "multi-user.target" "pteroq.service" ] + ++ (if thisConfig.server.enable then [ "nginx.service" ] else []); + + serviceConfig = { + Type = "oneshot"; + + User = thisConfig.php.user; + Group = thisConfig.php.group; + + ExecStart = pkgs.writeShellScript "pterodactyl-setup.sh" '' + SRC="${thisConfig.pkg}/share/php/pterodactyl-panel/"; + DEST="${thisConfig.php.root}"; + + USER="${thisConfig.php.user}"; + GROUP="${thisConfig.php.group}"; + + rm $DEST/* -r; + + for file in app bootstrap config database public resources routes vendor artisan; do + cp -r "$SRC/$file" "$DEST" + chmod -R 0550 "$DEST/$file" + done; + + mkdir -p -m 0750 "$DEST/bootstrap" + cp "$SRC/bootstrap/app.php" "$DEST/bootstrap/app.php"; + chmod -R 0550 "$DEST/bootstrap/app.php"; + + ln -s "${thisConfig.dataDir}/cache" "$DEST/bootstrap/cache"; + ln -s "${thisConfig.dataDir}/storage" "$DEST/storage"; + ''; + }; + }; + + pteroq = { + enable = true; + description = "Pterodactyl Queue Worker"; + after = [ "redis-${thisConfig.redis.name}.service" ]; + unitConfig = { StartLimitInterval = 180; }; + serviceConfig = { + User = thisConfig.php.user; + Group = thisConfig.php.group; + + WorkingDirectory = thisConfig.php.home; + + ExecStart = "${thisConfig.php.pkg}/bin/php ${thisConfig.php.home}/artisan queue:work --queue=high,standard,low --sleep=3 --tries=3"; + + Restart = "always"; + RestartSec = "5s"; + StartLimitBurst = 30; + }; + wantedBy = [ "multi-user.target" ]; + }; }; - wantedBy = [ "multi-user.target" ]; }; }; } diff --git a/packages/php.nix b/packages/php.nix index 6a6affa..9732524 100644 --- a/packages/php.nix +++ b/packages/php.nix @@ -1,12 +1,12 @@ -{ pkgs }: +{ pkgs ? import }: pkgs.php83.buildEnv { extensions = { enabled, all, }: enabled ++ (with all; [ redis - # xdebug + xdebug ]); - # extraConfig = '' - # xdebug.mode=debug - # ''; + extraConfig = '' + xdebug.mode=debug + ''; } diff --git a/packages/pterodactyl.nix b/packages/pterodactyl.nix index 15a8a24..6e3a168 100644 --- a/packages/pterodactyl.nix +++ b/packages/pterodactyl.nix @@ -1,9 +1,16 @@ -{ pkgs }: +{ pkgs ? import , php ? pkgs.php }: -let +php.buildComposerProject2 (finalAttrs: { + pname = "pterodactyl-panel"; version = "1.11.11"; -in pkgs.fetchzip { - url = "https://github.com/pterodactyl/panel/releases/download/v${ version }/panel.tar.gz"; - hash = "sha256-0nOHtReVUVXYQY/glS4x0gkbhetoXSWg4rRwOJlkcM8="; - stripRoot = false; -} + + src = pkgs.fetchzip { + url = "https://github.com/pterodactyl/panel/releases/download/v${finalAttrs.version}/panel.tar.gz"; + hash = "sha256-0nOHtReVUVXYQY/glS4x0gkbhetoXSWg4rRwOJlkcM8="; + stripRoot = false; + }; + + vendorHash = "sha256-WBzGGWCWNqvU4Ws7wBh8Ads7RBawBaxN1QNIUI4ivOQ="; + + inherit php; +}) diff --git a/packages/wings.nix b/packages/wings.nix index 9309948..ed923c5 100644 --- a/packages/wings.nix +++ b/packages/wings.nix @@ -1,4 +1,4 @@ -{ pkgs }: +{ pkgs ? import }: let version = "1.11.13";