diff --git a/flake.nix b/flake.nix index b74252b..ae537da 100644 --- a/flake.nix +++ b/flake.nix @@ -2,7 +2,7 @@ description = "Nixos modules for the pterodactyl game server panel"; inputs = { - nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; + nixpkgs.url = github:nixos/nixpkgs?ref=nixos-unstable; }; outputs = { self, nixpkgs }: { @@ -11,9 +11,14 @@ ); 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 { + wings = import ./packages/wings.nix { inherit pkgs; }; + pterodactyl = import ./packages/pterodactyl.nix { inherit pkgs; }; + php = import ./packages/php.nix { inherit pkgs; }; + composer = import ./packages/composer.nix { inherit pkgs php; }; + } + ); }; } diff --git a/modules/pterodactyl.nix b/modules/pterodactyl.nix index 7dfbc1c..2e88810 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 = "/var/lib/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,64 @@ 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; + }; + + home = lib.mkOption { + type = lib.types.path; + description = '' + Where Pterodactyl stores its stateful data is hardcoded to be right next to its php + scripts. But since we'd like to store the latter in the nix store and the nix store is + immutable, we have to find a workaround. + + So, the directory pointed to by this option will be where we instruct php to find its + scripts and data. And the actual files will be simlinked to from this directory, so we can + actually store them in a different location. + ''; + default = "/var/lib/pterodactyl/"; + }; + + manageHome = lib.mkOption { + type = lib.types.bool; + description = '' + Whether or not to automatically create the symlinks + + See services.pterodactyl.php.home for details. + ''; + default = true; + }; + + pkg = lib.mkOption { + type = lib.types.package; + description = "The php package to use"; + default = flake.outputs.packages.${pkgs.system}.php; + }; }; redis = { @@ -67,29 +120,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 = thisConfig.php.home; + 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 cfg.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 +162,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 +188,7 @@ in { }; services.phpfpm.pools.pterodactyl = { - user = cfg.user; + user = thisConfig.php.user; settings = { "listen.owner" = config.services.nginx.user; "pm" = "dynamic"; @@ -145,17 +206,49 @@ in { }; }; + systemd.tmpfiles.settings."10-pterodactyl" = lib.mkIf thisConfig.php.manageHome { + "${thisConfig.php.home}/app" = { "L" = { argument = "${thisConfig.pkg}/app"; }; }; + "${thisConfig.php.home}/config" = { "L" = { argument = "${thisConfig.pkg}/config"; }; }; + "${thisConfig.php.home}/database" = { "L" = { argument = "${thisConfig.pkg}/database"; }; }; + "${thisConfig.php.home}/public" = { "L" = { argument = "${thisConfig.pkg}/public"; }; }; + "${thisConfig.php.home}/resources" = { "L" = { argument = "${thisConfig.pkg}/resources"; }; }; + "${thisConfig.php.home}/routes" = { "L" = { argument = "${thisConfig.pkg}/routes"; }; }; + "${thisConfig.php.home}/tests" = { "L" = { argument = "${thisConfig.pkg}/tests"; }; }; + "${thisConfig.php.home}/artisan" = { "L" = { argument = "${thisConfig.pkg}/artisan"; }; }; + "${thisConfig.php.home}/compser.json" = { "L" = { argument = "${thisConfig.pkg}/compser.json"; }; }; + "${thisConfig.php.home}/compser.lock" = { "L" = { argument = "${thisConfig.pkg}/composer.lock"; }; }; + + "${thisConfig.php.home}/bootstrap/app.php" = { + "L" = { argument = "${thisConfig.pkg}/bootstrap/app.php"; }; + }; + "${thisConfig.php.home}/bootstrap/tests.php" = { + "L" = { argument = "${thisConfig.pkg}/bootstrap/tests.php"; }; + }; + "${thisConfig.php.home}/bootstrap/cache" = { + "L" = { argument = "${thisConfig.dataDir}/cache"; }; + }; + + "${thisConfig.php.home}/storage" = { "L" = { argument = "${thisConfig.dataDir}/storage"; }; }; + + "${thisConfig.dataDir}/storage" = { + "d" = { user = thisConfig.php.user; group = thisConfig.php.group; mode = "750"; }; + }; + "${thisConfig.dataDir}/cache" = { + "d" = { user = thisConfig.php.user; group = thisConfig.php.group; mode = "750"; }; + }; + }; + systemd.services.pteroq = { enable = true; description = "Pterodactyl Queue Worker"; - after = [ "redis-${cfg.redis.name}.service" ]; + after = [ "redis-${thisConfig.redis.name}.service" ]; unitConfig = { StartLimitInterval = 180; }; serviceConfig = { - User = cfg.user; - Group = cfg.user; + User = thisConfig.php.user; + Group = thisConfig.php.group; Restart = "always"; ExecStart = - "${flakePkgs.php}/bin/php ${cfg.pkg}/artisan queue:work --queue=high,standard,low --sleep=3 --tries=3"; + "${thisConfig.php.pkg}/bin/php ${thisConfig.php.home}/artisan queue:work --queue=high,standard,low --sleep=3 --tries=3"; StartLimitBurst = 30; RestartSec = "5s"; }; diff --git a/packages/composer.nix b/packages/composer.nix new file mode 100644 index 0000000..312e6d5 --- /dev/null +++ b/packages/composer.nix @@ -0,0 +1,5 @@ +{ pkgs ? import , php ? null }: + +let + php = if php == null then pkgs.php else php; +in php.packages.composer.override {php = phpWithExtensions;}; 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..1b573ae 100644 --- a/packages/pterodactyl.nix +++ b/packages/pterodactyl.nix @@ -1,9 +1,9 @@ -{ pkgs }: +{ pkgs ? import }: let version = "1.11.11"; in pkgs.fetchzip { - url = "https://github.com/pterodactyl/panel/releases/download/v${ version }/panel.tar.gz"; + url = https://github.com/pterodactyl/panel/releases/download/v${version}/panel.tar.gz; hash = "sha256-0nOHtReVUVXYQY/glS4x0gkbhetoXSWg4rRwOJlkcM8="; stripRoot = false; } 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";