1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.services.phpfpm;
7
8 stateDir = "/run/phpfpm";
9
10 pidFile = "${stateDir}/phpfpm.pid";
11
12 mkPool = n: p: ''
13 [${n}]
14 listen = ${p.listen}
15 ${p.extraConfig}
16 '';
17
18 cfgFile = pkgs.writeText "phpfpm.conf" ''
19 [global]
20 pid = ${pidFile}
21 error_log = syslog
22 daemonize = yes
23 ${cfg.extraConfig}
24
25 ${concatStringsSep "\n" (mapAttrsToList mkPool cfg.pools)}
26
27 ${concatStringsSep "\n" (mapAttrsToList (n: v: "[${n}]\n${v}") cfg.poolConfigs)}
28 '';
29
30 phpIni = pkgs.writeText "php.ini" ''
31 ${readFile "${cfg.phpPackage}/etc/php.ini"}
32
33 ${cfg.phpOptions}
34 '';
35
36in {
37
38 options = {
39 services.phpfpm = {
40 extraConfig = mkOption {
41 type = types.lines;
42 default = "";
43 description = ''
44 Extra configuration that should be put in the global section of
45 the PHP FPM configuration file. Do not specify the options
46 <literal>pid</literal>, <literal>error_log</literal> or
47 <literal>daemonize</literal> here, since they are generated by
48 NixOS.
49 '';
50 };
51
52 phpPackage = mkOption {
53 type = types.package;
54 default = pkgs.php;
55 defaultText = "pkgs.php";
56 description = ''
57 The PHP package to use for running the FPM service.
58 '';
59 };
60
61 phpOptions = mkOption {
62 type = types.lines;
63 default = "";
64 example =
65 ''
66 date.timezone = "CET"
67 '';
68 description =
69 "Options appended to the PHP configuration file <filename>php.ini</filename>.";
70 };
71
72 poolConfigs = mkOption {
73 default = {};
74 type = types.attrsOf types.lines;
75 example = literalExample ''
76 { mypool = '''
77 listen = /run/phpfpm/mypool
78 user = nobody
79 pm = dynamic
80 pm.max_children = 75
81 pm.start_servers = 10
82 pm.min_spare_servers = 5
83 pm.max_spare_servers = 20
84 pm.max_requests = 500
85 ''';
86 }
87 '';
88 description = ''
89 A mapping between PHP FPM pool names and their configurations.
90 See the documentation on <literal>php-fpm.conf</literal> for
91 details on configuration directives. If no pools are defined,
92 the phpfpm service is disabled.
93 '';
94 };
95
96 pools = mkOption {
97 type = types.attrsOf (types.submodule (import ./pool-options.nix {
98 inherit lib;
99 }));
100 default = {};
101 description = ''
102 If no pools are defined, the phpfpm service is disabled.
103 '';
104 };
105 };
106 };
107
108 config = mkIf (cfg.pools != {} || cfg.poolConfigs != {}) {
109
110 systemd.services.phpfpm = {
111 wantedBy = [ "multi-user.target" ];
112 preStart = ''
113 mkdir -p "${stateDir}"
114 '';
115 serviceConfig = {
116 ExecStart = "${cfg.phpPackage}/bin/php-fpm -y ${cfgFile} -c ${phpIni}";
117 PIDFile = pidFile;
118 };
119 };
120
121 };
122}