diff options
Diffstat (limited to 'nixos/modules/services/web-servers/phpfpm/default.nix')
-rw-r--r-- | nixos/modules/services/web-servers/phpfpm/default.nix | 252 |
1 files changed, 177 insertions, 75 deletions
diff --git a/nixos/modules/services/web-servers/phpfpm/default.nix b/nixos/modules/services/web-servers/phpfpm/default.nix index ffafbc5e92f..e95e71e0d99 100644 --- a/nixos/modules/services/web-servers/phpfpm/default.nix +++ b/nixos/modules/services/web-servers/phpfpm/default.nix @@ -4,41 +4,27 @@ with lib; let cfg = config.services.phpfpm; - enabled = cfg.poolConfigs != {} || cfg.pools != {}; - stateDir = "/run/phpfpm"; + runtimeDir = "/run/phpfpm"; - poolConfigs = - (mapAttrs mapPoolConfig cfg.poolConfigs) // - (mapAttrs mapPool cfg.pools); + toStr = value: + if true == value then "yes" + else if false == value then "no" + else toString value; - mapPoolConfig = n: p: { - phpPackage = cfg.phpPackage; - phpOptions = cfg.phpOptions; - config = p; - }; - - mapPool = n: p: { - phpPackage = p.phpPackage; - phpOptions = p.phpOptions; - config = '' - listen = ${p.listen} - ${p.extraConfig} - ''; - }; - - fpmCfgFile = pool: conf: pkgs.writeText "phpfpm-${pool}.conf" '' + fpmCfgFile = pool: poolOpts: pkgs.writeText "phpfpm-${pool}.conf" '' [global] - error_log = syslog - daemonize = no - ${cfg.extraConfig} + ${concatStringsSep "\n" (mapAttrsToList (n: v: "${n} = ${toStr v}") cfg.settings)} + ${optionalString (cfg.extraConfig != null) cfg.extraConfig} [${pool}] - ${conf} + ${concatStringsSep "\n" (mapAttrsToList (n: v: "${n} = ${toStr v}") poolOpts.settings)} + ${concatStringsSep "\n" (mapAttrsToList (n: v: "env[${n}] = ${toStr v}") poolOpts.phpEnv)} + ${optionalString (poolOpts.extraConfig != null) poolOpts.extraConfig} ''; - phpIni = pool: pkgs.runCommand "php.ini" { - inherit (pool) phpPackage phpOptions; + phpIni = poolOpts: pkgs.runCommand "php.ini" { + inherit (poolOpts) phpPackage phpOptions; preferLocalBuild = true; nixDefaults = '' sendmail_path = "/run/wrappers/bin/sendmail -t -i" @@ -48,13 +34,138 @@ let cat $phpPackage/etc/php.ini $nixDefaultsPath $phpOptionsPath > $out ''; + poolOpts = { name, ... }: + let + poolOpts = cfg.pools."${name}"; + in + { + options = { + socket = mkOption { + type = types.str; + readOnly = true; + description = '' + Path to the unix socket file on which to accept FastCGI requests. + <note><para>This option is read-only and managed by NixOS.</para></note> + ''; + }; + + listen = mkOption { + type = types.str; + default = ""; + example = "/path/to/unix/socket"; + description = '' + The address on which to accept FastCGI requests. + ''; + }; + + phpPackage = mkOption { + type = types.package; + default = cfg.phpPackage; + defaultText = "config.services.phpfpm.phpPackage"; + description = '' + The PHP package to use for running this PHP-FPM pool. + ''; + }; + + phpOptions = mkOption { + type = types.lines; + default = cfg.phpOptions; + defaultText = "config.services.phpfpm.phpOptions"; + description = '' + "Options appended to the PHP configuration file <filename>php.ini</filename> used for this PHP-FPM pool." + ''; + }; + + phpEnv = lib.mkOption { + type = with types; attrsOf str; + default = {}; + description = '' + Environment variables used for this PHP-FPM pool. + ''; + example = literalExample '' + { + HOSTNAME = "$HOSTNAME"; + TMP = "/tmp"; + TMPDIR = "/tmp"; + TEMP = "/tmp"; + } + ''; + }; + + user = mkOption { + type = types.str; + description = "User account under which this pool runs."; + }; + + group = mkOption { + type = types.str; + description = "Group account under which this pool runs."; + }; + + settings = mkOption { + type = with types; attrsOf (oneOf [ str int bool ]); + default = {}; + description = '' + PHP-FPM pool directives. Refer to the "List of pool directives" section of + <link xlink:href="https://www.php.net/manual/en/install.fpm.configuration.php"/> + for details. Note that settings names must be enclosed in quotes (e.g. + <literal>"pm.max_children"</literal> instead of <literal>pm.max_children</literal>). + ''; + example = literalExample '' + { + "pm" = "dynamic"; + "pm.max_children" = 75; + "pm.start_servers" = 10; + "pm.min_spare_servers" = 5; + "pm.max_spare_servers" = 20; + "pm.max_requests" = 500; + } + ''; + }; + + extraConfig = mkOption { + type = with types; nullOr lines; + default = null; + description = '' + Extra lines that go into the pool configuration. + See the documentation on <literal>php-fpm.conf</literal> for + details on configuration directives. + ''; + }; + }; + + config = { + socket = if poolOpts.listen == "" then "${runtimeDir}/${name}.sock" else poolOpts.listen; + group = mkDefault poolOpts.user; + + settings = mapAttrs (name: mkDefault){ + listen = poolOpts.socket; + user = poolOpts.user; + group = poolOpts.group; + }; + }; + }; + in { options = { services.phpfpm = { + settings = mkOption { + type = with types; attrsOf (oneOf [ str int bool ]); + default = {}; + description = '' + PHP-FPM global directives. Refer to the "List of global php-fpm.conf directives" section of + <link xlink:href="https://www.php.net/manual/en/install.fpm.configuration.php"/> + for details. Note that settings names must be enclosed in quotes (e.g. + <literal>"pm.max_children"</literal> instead of <literal>pm.max_children</literal>). + You need not specify the options <literal>error_log</literal> or + <literal>daemonize</literal> here, since they are generated by NixOS. + ''; + }; + extraConfig = mkOption { - type = types.lines; - default = ""; + type = with types; nullOr lines; + default = null; description = '' Extra configuration that should be put in the global section of the PHP-FPM configuration file. Do not specify the options @@ -80,64 +191,56 @@ in { '' date.timezone = "CET" ''; - description = - "Options appended to the PHP configuration file <filename>php.ini</filename>."; - }; - - poolConfigs = mkOption { - default = {}; - type = types.attrsOf types.lines; - example = literalExample '' - { mypool = ''' - listen = /run/phpfpm/mypool - user = nobody - pm = dynamic - pm.max_children = 75 - pm.start_servers = 10 - pm.min_spare_servers = 5 - pm.max_spare_servers = 20 - pm.max_requests = 500 - '''; - } - ''; description = '' - A mapping between PHP-FPM pool names and their configurations. - See the documentation on <literal>php-fpm.conf</literal> for - details on configuration directives. If no pools are defined, - the phpfpm service is disabled. + Options appended to the PHP configuration file <filename>php.ini</filename>. ''; }; pools = mkOption { - type = types.attrsOf (types.submodule (import ./pool-options.nix { - inherit lib config; - })); + type = types.attrsOf (types.submodule poolOpts); default = {}; example = literalExample '' { mypool = { - listen = "/path/to/unix/socket"; + user = "php"; + group = "php"; phpPackage = pkgs.php; - extraConfig = ''' - user = nobody - pm = dynamic - pm.max_children = 75 - pm.start_servers = 10 - pm.min_spare_servers = 5 - pm.max_spare_servers = 20 - pm.max_requests = 500 + settings = ''' + "pm" = "dynamic"; + "pm.max_children" = 75; + "pm.start_servers" = 10; + "pm.min_spare_servers" = 5; + "pm.max_spare_servers" = 20; + "pm.max_requests" = 500; '''; } }''; description = '' - PHP-FPM pools. If no pools or poolConfigs are defined, the PHP-FPM + PHP-FPM pools. If no pools are defined, the PHP-FPM service is disabled. ''; }; }; }; - config = mkIf enabled { + config = mkIf (cfg.pools != {}) { + + warnings = + mapAttrsToList (pool: poolOpts: '' + Using config.services.phpfpm.pools.${pool}.listen is deprecated and will become unsupported in a future release. Please reference the read-only option config.services.phpfpm.pools.${pool}.socket to access the path of your socket. + '') (filterAttrs (pool: poolOpts: poolOpts.listen != "") cfg.pools) ++ + mapAttrsToList (pool: poolOpts: '' + Using config.services.phpfpm.pools.${pool}.extraConfig is deprecated and will become unsupported in a future release. Please migrate your configuration to config.services.phpfpm.pools.${pool}.settings. + '') (filterAttrs (pool: poolOpts: poolOpts.extraConfig != null) cfg.pools) ++ + optional (cfg.extraConfig != null) '' + Using config.services.phpfpm.extraConfig is deprecated and will become unsupported in a future release. Please migrate your configuration to config.services.phpfpm.settings. + '' + ; + + services.phpfpm.settings = { + error_log = "syslog"; + daemonize = false; + }; systemd.slices.phpfpm = { description = "PHP FastCGI Process manager pools slice"; @@ -148,18 +251,15 @@ in { wantedBy = [ "multi-user.target" ]; }; - systemd.services = flip mapAttrs' poolConfigs (pool: poolConfig: + systemd.services = mapAttrs' (pool: poolOpts: nameValuePair "phpfpm-${pool}" { description = "PHP FastCGI Process Manager service for pool ${pool}"; after = [ "network.target" ]; wantedBy = [ "phpfpm.target" ]; partOf = [ "phpfpm.target" ]; - preStart = '' - mkdir -p ${stateDir} - ''; serviceConfig = let - cfgFile = fpmCfgFile pool poolConfig.config; - iniFile = phpIni poolConfig; + cfgFile = fpmCfgFile pool poolOpts; + iniFile = phpIni poolOpts; in { Slice = "phpfpm.slice"; PrivateDevices = true; @@ -168,10 +268,12 @@ in { # XXX: We need AF_NETLINK to make the sendmail SUID binary from postfix work RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6 AF_NETLINK"; Type = "notify"; - ExecStart = "${poolConfig.phpPackage}/bin/php-fpm -y ${cfgFile} -c ${iniFile}"; + ExecStart = "${poolOpts.phpPackage}/bin/php-fpm -y ${cfgFile} -c ${iniFile}"; ExecReload = "${pkgs.coreutils}/bin/kill -USR2 $MAINPID"; + RuntimeDirectory = "phpfpm"; + RuntimeDirectoryPreserve = true; # Relevant when multiple processes are running }; } - ); + ) cfg.pools; }; } |