at 18.09-beta 4.5 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.phpfpm; 7 enabled = cfg.poolConfigs != {} || cfg.pools != {}; 8 9 stateDir = "/run/phpfpm"; 10 11 poolConfigs = cfg.poolConfigs // mapAttrs mkPool cfg.pools; 12 13 mkPool = n: p: '' 14 listen = ${p.listen} 15 ${p.extraConfig} 16 ''; 17 18 fpmCfgFile = pool: poolConfig: pkgs.writeText "phpfpm-${pool}.conf" '' 19 [global] 20 error_log = syslog 21 daemonize = no 22 ${cfg.extraConfig} 23 24 [${pool}] 25 ${poolConfig} 26 ''; 27 28 phpIni = pkgs.runCommand "php.ini" { 29 inherit (cfg) phpPackage phpOptions; 30 nixDefaults = '' 31 sendmail_path = "/run/wrappers/bin/sendmail -t -i" 32 ''; 33 passAsFile = [ "nixDefaults" "phpOptions" ]; 34 } '' 35 cat $phpPackage/etc/php.ini $nixDefaultsPath $phpOptionsPath > $out 36 ''; 37 38in { 39 40 options = { 41 services.phpfpm = { 42 extraConfig = mkOption { 43 type = types.lines; 44 default = ""; 45 description = '' 46 Extra configuration that should be put in the global section of 47 the PHP-FPM configuration file. Do not specify the options 48 <literal>error_log</literal> or 49 <literal>daemonize</literal> here, since they are generated by 50 NixOS. 51 ''; 52 }; 53 54 phpPackage = mkOption { 55 type = types.package; 56 default = pkgs.php; 57 defaultText = "pkgs.php"; 58 description = '' 59 The PHP package to use for running the PHP-FPM service. 60 ''; 61 }; 62 63 phpOptions = mkOption { 64 type = types.lines; 65 default = ""; 66 example = 67 '' 68 date.timezone = "CET" 69 ''; 70 description = 71 "Options appended to the PHP configuration file <filename>php.ini</filename>."; 72 }; 73 74 poolConfigs = mkOption { 75 default = {}; 76 type = types.attrsOf types.lines; 77 example = literalExample '' 78 { mypool = ''' 79 listen = /run/phpfpm/mypool 80 user = nobody 81 pm = dynamic 82 pm.max_children = 75 83 pm.start_servers = 10 84 pm.min_spare_servers = 5 85 pm.max_spare_servers = 20 86 pm.max_requests = 500 87 '''; 88 } 89 ''; 90 description = '' 91 A mapping between PHP-FPM pool names and their configurations. 92 See the documentation on <literal>php-fpm.conf</literal> for 93 details on configuration directives. If no pools are defined, 94 the phpfpm service is disabled. 95 ''; 96 }; 97 98 pools = mkOption { 99 type = types.attrsOf (types.submodule (import ./pool-options.nix { 100 inherit lib; 101 })); 102 default = {}; 103 example = literalExample '' 104 { 105 mypool = { 106 listen = "/path/to/unix/socket"; 107 extraConfig = ''' 108 user = nobody 109 pm = dynamic 110 pm.max_children = 75 111 pm.start_servers = 10 112 pm.min_spare_servers = 5 113 pm.max_spare_servers = 20 114 pm.max_requests = 500 115 '''; 116 } 117 }''; 118 description = '' 119 PHP-FPM pools. If no pools or poolConfigs are defined, the PHP-FPM 120 service is disabled. 121 ''; 122 }; 123 }; 124 }; 125 126 config = mkIf enabled { 127 128 systemd.slices.phpfpm = { 129 description = "PHP FastCGI Process manager pools slice"; 130 }; 131 132 systemd.targets.phpfpm = { 133 description = "PHP FastCGI Process manager pools target"; 134 wantedBy = [ "multi-user.target" ]; 135 }; 136 137 systemd.services = flip mapAttrs' poolConfigs (pool: poolConfig: 138 nameValuePair "phpfpm-${pool}" { 139 description = "PHP FastCGI Process Manager service for pool ${pool}"; 140 after = [ "network.target" ]; 141 wantedBy = [ "phpfpm.target" ]; 142 partOf = [ "phpfpm.target" ]; 143 preStart = '' 144 mkdir -p ${stateDir} 145 ''; 146 serviceConfig = let 147 cfgFile = fpmCfgFile pool poolConfig; 148 in { 149 Slice = "phpfpm.slice"; 150 PrivateDevices = true; 151 ProtectSystem = "full"; 152 ProtectHome = true; 153 # XXX: We need AF_NETLINK to make the sendmail SUID binary from postfix work 154 RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6 AF_NETLINK"; 155 Type = "notify"; 156 ExecStart = "${cfg.phpPackage}/bin/php-fpm -y ${cfgFile} -c ${phpIni}"; 157 ExecReload = "${pkgs.coreutils}/bin/kill -USR2 $MAINPID"; 158 }; 159 } 160 ); 161 }; 162}