From 63d52c2fd4e6099ec651ba0833a29a29245935e2 Mon Sep 17 00:00:00 2001 From: Fiona Grzebien Date: Tue, 22 Oct 2024 09:38:38 +0200 Subject: [PATCH] pterodactyl panel and wings --- .gitignore | 1 + flake.lock | 27 ++++++++++ flake.nix | 20 +++++++ modules/panel.nix | 135 ++++++++++++++++++++++++++++++++++++++++++++++ modules/wings.nix | 53 ++++++++++++++++++ pkgs/wings.nix | 20 +++++++ 6 files changed, 256 insertions(+) create mode 100644 .gitignore create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 modules/panel.nix create mode 100644 modules/wings.nix create mode 100644 pkgs/wings.nix 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.lock b/flake.lock new file mode 100644 index 0000000..af2f347 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1729265718, + "narHash": "sha256-4HQI+6LsO3kpWTYuVGIzhJs1cetFcwT7quWCk/6rqeo=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "ccc0c2126893dd20963580b6478d1a10a4512185", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..aaae941 --- /dev/null +++ b/flake.nix @@ -0,0 +1,20 @@ +{ + description = "Pterodactyl Wings"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + }; + + outputs = { self, nixpkgs }: + { + packages."x86_64-linux".pterodactyl-wings = nixpkgs.legacyPackages."x86_64-linux".callPackage ./pkgs/wings.nix { }; + packages."x86_64-linux".default = self.packages."x86_64-linux".pterodactyl-wings; + + packages."aarch64-linux".pterodactyl-wings = nixpkgs.legacyPackages."aarch64-linux".callPackage ./pkgs/wings.nix { }; + packages."aarch64-linux".default = self.packages."aarch64-linux".pterodactyl-wings; + + nixosModules.pterodactyl-panel = ./modules/panel.nix; + nixosModules.pterodactyl-wings = ./modules/wings.nix; + nixosModules.default = self.nixosModules.pterodactyl-wings; + }; +} diff --git a/modules/panel.nix b/modules/panel.nix new file mode 100644 index 0000000..ce3fdff --- /dev/null +++ b/modules/panel.nix @@ -0,0 +1,135 @@ +{ lib, config, pkgs, ... }: +with lib; +let + cfg = config.services.pterodactyl; + pterodactlyPhp83 = (pkgs.php83.buildEnv { + extensions = { enabled, all, }: enabled ++ (with all; [ redis xdebug ]); + extraConfig = '' + xdebug.mode=debug + ''; + }); +in { + options.services.pterodactyl = { + enable = mkOption { + type = types.bool; + default = false; + }; + nginxVhost = mkOption { + type = types.str; + description = mdDoc '' + The Nginx virtual host, on which the panel will run. + ''; + default = "localhost"; + example = literalExpression "mgr.matestmc.net"; + }; + user = mkOption { + type = types.str; + description = mdDoc '' + The user that Nginx and the panel will run with. + ''; + default = "pterodactyl"; + example = literalExpression "pterodactyl"; + }; + dataDir = mkOption { + type = types.str; + description = mdDoc '' + The directory with the panel files. + Usually /srv/pterodactyl or /var/www/pterodactyl. + ''; + default = "/srv/pterodactyl"; + example = literalExpression "/srv/pterodactyl"; + }; + redisName = mkOption { + type = types.str; + description = mdDoc '' + The Redis server name. + ''; + default = "pterodactis"; + }; + }; + + config = mkIf cfg.enable { + services.redis.servers.${cfg.redisName} = { + enable = true; + port = 6379; + }; + services.nginx = { + enable = true; + user = cfg.user; + virtualHosts."${cfg.nginxVhost}" = { + root = "${cfg.dataDir}/public"; + extraConfig = '' + index index.html index.htm index.php; + ''; + locations = { + "~ \\.php$" = { + extraConfig = '' + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass unix:${config.services.phpfpm.pools.pterodactyl.socket}; + include ${pkgs.nginx}/conf/fastcgi_params; + fastcgi_index index.php; + fastcgi_param PHP_VALUE "upload_max_filesize = 100M \n post_max_size=100M"; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param HTTP_PROXY ""; + fastcgi_intercept_errors off; + fastcgi_buffer_size 16k; + fastcgi_buffers 4 16k; + fastcgi_connect_timeout 300; + fastcgi_send_timeout 300; + fastcgi_read_timeout 300; + ''; + }; + "/" = { tryFiles = "$uri $uri/ /index.php?$query_string"; }; + }; + }; + }; + services.phpfpm.pools.pterodactyl = { + user = cfg.user; + settings = { + "listen.owner" = config.services.nginx.user; + "pm" = "dynamic"; + "pm.start_servers" = 4; + "pm.min_spare_servers" = 4; + "pm.max_spare_servers" = 16; + "pm.max_children" = 64; + "pm.max_requests" = 256; + + "clear_env" = false; + "catch_workers_output" = true; + "decorate_workers_output" = false; + "php_admin_value[error_log]" = "stderr"; + "php_admin_flag[daemonize]" = "false"; + }; + }; + users.users.${cfg.user} = { + isSystemUser = true; + createHome = true; + home = cfg.dataDir; + group = cfg.user; + }; + users.groups.${cfg.user} = { }; + + systemd.services.pteroq = { + enable = true; + description = "Pterodactyl Queue Worker"; + after = [ "redis-${cfg.redisName}.service" ]; + unitConfig = { StartLimitInterval = 180; }; + serviceConfig = { + User = cfg.user; + Group = cfg.user; + Restart = "always"; + ExecStart = + "${pterodactlyPhp83}/bin/php ${cfg.dataDir}/artisan queue:work --queue=high,standard,low --sleep=3 --tries=3"; + StartLimitBurst = 30; + RestartSec = "5s"; + }; + wantedBy = [ "multi-user.target" ]; + }; + + environment.systemPackages = [ + pterodactlyPhp83 + # composer + (pkgs.php83Packages.composer.override { php = pterodactlyPhp83; }) + ]; + }; +} diff --git a/modules/wings.nix b/modules/wings.nix new file mode 100644 index 0000000..36709e0 --- /dev/null +++ b/modules/wings.nix @@ -0,0 +1,53 @@ +{ lib, config, pkgs, ... }: +with lib; +let + configuration = '' + # managed by NixOS + '' + "${config.services.wings.configuration}"; +in { + options.services.wings = { + enable = mkOption { + type = types.bool; + default = false; + }; + configuration = mkOption { + type = types.str; + default = null; + }; + pkg = mkOption { + type = types.package; + default = pkgs.pterodactyl-wings; + }; + }; + + config = mkIf config.services.wings.enable { + assertions = [{ + assertion = config.services.wings.configuration != null; + message = "wings is enabled, configuration must be set."; + }]; + + virtualisation.docker.enable = true; + environment.etc."pterodactyl/config.yml".text = configuration; + environment.systemPackages = [ config.services.wings.pkg ]; + systemd.services.wings = { + enable = cfg.enable; + description = "Pterodactyl Wings daemon"; + after = [ "docker.service" ]; + partOf = [ "docker.service" ]; + requires = [ "docker.service" ]; + startLimitIntervalSec = 180; + startLimitBurst = 30; + serviceConfig = { + User = "root"; + WorkingDirectory = "/run/wings"; + LimitNOFILE = 4096; + PIDFile = "/var/run/wings/daemon.pid"; + ExecStart = + "/bin/sh -c '/usr/bin/env mkdir /run/wings; /usr/bin/env cat /etc/pterodactyl/config.yml > /run/wings/config.yml; ${config.services.wings.pkg}/bin/wings --config /run/wings/config.yml'"; + Restart = "on-failure"; + RestartSec = "5s"; + }; + wantedBy = [ "multi-user.target" ]; + }; + }; +} diff --git a/pkgs/wings.nix b/pkgs/wings.nix new file mode 100644 index 0000000..6e2806e --- /dev/null +++ b/pkgs/wings.nix @@ -0,0 +1,20 @@ +{ lib, buildGoModule, fetchFromGitHub }: + +buildGoModule rec { + pname = "pterodactyl-wings"; + version = "1.11.13"; + + src = fetchFromGitHub { + owner = "pterodactyl"; + repo = "wings"; + rev = "v${version}"; + sha256 = "sha256-UpYUHWM2J8nH+srdKSpFQEaPx2Rj2+YdphV8jJXcoBU="; + }; + + vendorHash = "sha256-eWfQE9cQ7zIkITWwnVu9Sf9vVFjkQih/ZW77d6p/Iw0="; + #subPackages = [ "." ]; + + ldflags = [ + "-X github.com/pterodactyl/wings/system.Version=${version}" + ]; +}