|
|
|
@ -4,37 +4,26 @@ with lib; |
|
|
|
|
|
|
|
|
|
let |
|
|
|
|
cfg = config.services.phpfpm; |
|
|
|
|
enabled = cfg.poolConfigs != {} || cfg.pools != {}; |
|
|
|
|
enabled = cfg.pools != {}; |
|
|
|
|
|
|
|
|
|
stateDir = "/run/phpfpm"; |
|
|
|
|
|
|
|
|
|
poolConfigs = |
|
|
|
|
(mapAttrs mapPoolConfig cfg.poolConfigs) // |
|
|
|
|
(mapAttrs mapPool cfg.pools); |
|
|
|
|
|
|
|
|
|
mapPoolConfig = n: p: { |
|
|
|
|
phpPackage = cfg.phpPackage; |
|
|
|
|
phpOptions = cfg.phpOptions; |
|
|
|
|
config = p; |
|
|
|
|
}; |
|
|
|
|
poolConfigs = (mapAttrs mapPool cfg.pools); |
|
|
|
|
|
|
|
|
|
mapPool = n: p: { |
|
|
|
|
phpPackage = p.phpPackage; |
|
|
|
|
phpOptions = p.phpOptions; |
|
|
|
|
config = '' |
|
|
|
|
listen = ${p.listen} |
|
|
|
|
${p.extraConfig} |
|
|
|
|
''; |
|
|
|
|
userPool = p.user; |
|
|
|
|
groupPool = p.group; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
fpmCfgFile = pool: conf: pkgs.writeText "phpfpm-${pool}.conf" '' |
|
|
|
|
[global] |
|
|
|
|
error_log = syslog |
|
|
|
|
daemonize = no |
|
|
|
|
${cfg.extraConfig} |
|
|
|
|
${cfg.globalExtraConfig} |
|
|
|
|
|
|
|
|
|
[${pool}] |
|
|
|
|
${conf} |
|
|
|
|
listen = /run/phpfpm-${pool}/${cfg.pools.${pool}.socketName}.sock |
|
|
|
|
${cfg.pools.${pool}.extraConfig} |
|
|
|
|
''; |
|
|
|
|
|
|
|
|
|
phpIni = pool: pkgs.runCommand "php.ini" { |
|
|
|
@ -49,86 +38,99 @@ let |
|
|
|
|
''; |
|
|
|
|
|
|
|
|
|
in { |
|
|
|
|
|
|
|
|
|
options = { |
|
|
|
|
services.phpfpm = { |
|
|
|
|
extraConfig = mkOption { |
|
|
|
|
globalExtraConfig = mkOption { |
|
|
|
|
type = types.lines; |
|
|
|
|
default = ""; |
|
|
|
|
description = '' |
|
|
|
|
Extra configuration that should be put in the global section of |
|
|
|
|
Global extra configuration that should be put in the global section of |
|
|
|
|
the PHP-FPM configuration file. Do not specify the options |
|
|
|
|
<literal>error_log</literal> or |
|
|
|
|
<literal>daemonize</literal> here, since they are generated by |
|
|
|
|
NixOS. |
|
|
|
|
''; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
phpPackage = mkOption { |
|
|
|
|
type = types.package; |
|
|
|
|
default = pkgs.php; |
|
|
|
|
defaultText = "pkgs.php"; |
|
|
|
|
description = '' |
|
|
|
|
The PHP package to use for running the PHP-FPM service. |
|
|
|
|
<literal>daemonize</literal> here, since they are generated by NixOS. |
|
|
|
|
''; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
phpOptions = mkOption { |
|
|
|
|
type = types.lines; |
|
|
|
|
default = ""; |
|
|
|
|
example = |
|
|
|
|
'' |
|
|
|
|
date.timezone = "CET" |
|
|
|
|
''; |
|
|
|
|
description = |
|
|
|
|
"Options appended to the PHP configuration file <filename>php.ini</filename>."; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
poolConfigs = mkOption { |
|
|
|
|
pools = mkOption { |
|
|
|
|
default = {}; |
|
|
|
|
type = types.attrsOf types.lines; |
|
|
|
|
type = types.attrsOf (types.submodule { |
|
|
|
|
options = { |
|
|
|
|
socketName = mkOption { |
|
|
|
|
type = types.str; |
|
|
|
|
example = "php-fpm"; |
|
|
|
|
description = '' |
|
|
|
|
The address on which to accept FastCGI requests. |
|
|
|
|
''; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
phpPackage = mkOption { |
|
|
|
|
type = types.package; |
|
|
|
|
default = fpmCfg.phpPackage; |
|
|
|
|
defaultText = "config.services.phpfpm.phpPackage"; |
|
|
|
|
description = '' |
|
|
|
|
The PHP package to use for running this PHP-FPM pool. |
|
|
|
|
''; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
phpOptions = mkOption { |
|
|
|
|
type = types.lines; |
|
|
|
|
default = fpmCfg.phpOptions; |
|
|
|
|
defaultText = "config.services.phpfpm.phpOptions"; |
|
|
|
|
description = '' |
|
|
|
|
"Options appended to the PHP configuration file <filename>php.ini</filename> used for this PHP-FPM pool." |
|
|
|
|
''; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
user = mkOption { |
|
|
|
|
type = types.string; |
|
|
|
|
default = "phpfpm"; |
|
|
|
|
description = "User account under which phpfpm runs."; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
group = mkOption { |
|
|
|
|
type = types.string; |
|
|
|
|
default = "phpfpm"; |
|
|
|
|
description = "Group account under which phpfpm runs."; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
extraConfig = mkOption { |
|
|
|
|
type = types.lines; |
|
|
|
|
example = '' |
|
|
|
|
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 = '' |
|
|
|
|
Extra lines that go into the pool configuration. |
|
|
|
|
See the documentation on <literal>php-fpm.conf</literal> for |
|
|
|
|
details on configuration directives. |
|
|
|
|
''; |
|
|
|
|
}; |
|
|
|
|
}; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
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 |
|
|
|
|
'''; |
|
|
|
|
{ |
|
|
|
|
mypool = { |
|
|
|
|
socketName = "example"; |
|
|
|
|
phpPackage = pkgs.php; |
|
|
|
|
user = "phpfpm"; |
|
|
|
|
group = "phpfpm"; |
|
|
|
|
extraConfig = ''' |
|
|
|
|
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. |
|
|
|
|
''; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
pools = mkOption { |
|
|
|
|
type = types.attrsOf (types.submodule (import ./pool-options.nix { |
|
|
|
|
inherit lib config; |
|
|
|
|
})); |
|
|
|
|
default = {}; |
|
|
|
|
example = literalExample '' |
|
|
|
|
{ |
|
|
|
|
mypool = { |
|
|
|
|
listen = "/path/to/unix/socket"; |
|
|
|
|
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 |
|
|
|
|
'''; |
|
|
|
|
} |
|
|
|
|
}''; |
|
|
|
|
description = '' |
|
|
|
|
PHP-FPM pools. If no pools or poolConfigs are defined, the PHP-FPM |
|
|
|
|
service is disabled. |
|
|
|
@ -154,9 +156,6 @@ in { |
|
|
|
|
after = [ "network.target" ]; |
|
|
|
|
wantedBy = [ "phpfpm.target" ]; |
|
|
|
|
partOf = [ "phpfpm.target" ]; |
|
|
|
|
preStart = '' |
|
|
|
|
mkdir -p ${stateDir} |
|
|
|
|
''; |
|
|
|
|
serviceConfig = let |
|
|
|
|
cfgFile = fpmCfgFile pool poolConfig.config; |
|
|
|
|
iniFile = phpIni poolConfig; |
|
|
|
@ -166,10 +165,19 @@ in { |
|
|
|
|
ProtectSystem = "full"; |
|
|
|
|
ProtectHome = true; |
|
|
|
|
# XXX: We need AF_NETLINK to make the sendmail SUID binary from postfix work |
|
|
|
|
RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6 AF_NETLINK"; |
|
|
|
|
RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" "AF_NETLINK" ]; |
|
|
|
|
Type = "notify"; |
|
|
|
|
ExecStart = "${poolConfig.phpPackage}/bin/php-fpm -y ${cfgFile} -c ${iniFile}"; |
|
|
|
|
ExecStart = "${poolConfig.phpPackage}/bin/php-fpm -y '${cfgFile}' -c '${iniFile}'"; |
|
|
|
|
ExecReload = "${pkgs.coreutils}/bin/kill -USR2 $MAINPID"; |
|
|
|
|
# User and group |
|
|
|
|
User = "${poolConfig.userPool}"; |
|
|
|
|
Group = "${poolConfig.groupPool}"; |
|
|
|
|
# Runtime directory and mode |
|
|
|
|
RuntimeDirectory = "phpfpm-${pool}"; |
|
|
|
|
RuntimeDirectoryMode = "0750"; |
|
|
|
|
# Capabilities |
|
|
|
|
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" "CAP_SETGID" "CAP_SETUID" "CAP_CHOWN" "CAP_SYS_RESOURCE" ]; |
|
|
|
|
CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" "CAP_SETGID" "CAP_SETUID" "CAP_CHOWN" "CAP_SYS_RESOURCE" ]; |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
); |
|
|
|
|