]> git.immae.eu Git - perso/Immae/Config/Nix.git/blame - nixops/modules/websites/phpfpm/default.nix
Move webstats outside of nixops
[perso/Immae/Config/Nix.git] / nixops / modules / websites / phpfpm / default.nix
CommitLineData
98584540
IB
1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.services.myPhpfpm;
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 = poolPhpOptions: (pkgs.runCommand "php.ini" {
29 inherit (cfg) phpPackage phpOptions;
30 inherit poolPhpOptions;
31 nixDefaults = ''
32 sendmail_path = "/run/wrappers/bin/sendmail -t -i"
33 '';
34 passAsFile = [ "nixDefaults" "phpOptions" "poolPhpOptions" ];
35 } ''
36 cat $phpPackage/etc/php.ini $nixDefaultsPath $phpOptionsPath $poolPhpOptionsPath > $out
37 '');
38
39in {
40
41 options = {
42 services.myPhpfpm = {
43 extraConfig = mkOption {
44 type = types.lines;
45 default = "";
46 description = ''
47 Extra configuration that should be put in the global section of
48 the PHP-FPM configuration file. Do not specify the options
49 <literal>error_log</literal> or
50 <literal>daemonize</literal> here, since they are generated by
51 NixOS.
52 '';
53 };
54
55 phpPackage = mkOption {
56 type = types.package;
57 default = pkgs.php;
58 defaultText = "pkgs.php";
59 description = ''
60 The PHP package to use for running the PHP-FPM service.
61 '';
62 };
63
64 phpOptions = mkOption {
65 type = types.lines;
66 default = "";
67 example =
68 ''
69 date.timezone = "CET"
70 '';
71 description =
72 "Options appended to the PHP configuration file <filename>php.ini</filename>.";
73 };
74
98163486
IB
75 serviceDependencies = mkOption {
76 default = {};
77 type = types.attrsOf (types.listOf types.string);
78 example = literalExample ''
79 { mypool = ["postgresql.service"]; }
80 '';
81 description = ''
82 Extra service dependencies specific to pool.
83 '';
84 };
85
5f08b34c
IB
86 envFile = mkOption {
87 default = {};
88 type = types.attrsOf types.string;
89 example = literalExample ''
90 { mypool = "path/to/file";
91 }
92 '';
93 description = ''
94 Extra environment file go into the service script.
95 '';
96 };
97
8eded9ec
IB
98 preStart = mkOption {
99 default = {};
100 type = types.attrsOf types.lines;
101 example = literalExample ''
102 { mypool = '''
103 touch foo
104 ''';
105 }
106 '';
107 description = ''
108 Extra lines that will go into the preStart systemd service
109 '';
110 };
111
98584540
IB
112 poolPhpConfigs = mkOption {
113 default = {};
114 type = types.attrsOf types.lines;
115 example = literalExample ''
116 { mypool = '''
117 extension = some_extension.so
118 ''';
119 }
120 '';
121 description = ''
122 Extra lines that go into the php configuration specific to pool.
123 '';
124 };
125
126 poolConfigs = mkOption {
127 default = {};
128 type = types.attrsOf types.lines;
129 example = literalExample ''
130 { mypool = '''
131 listen = /run/phpfpm/mypool
132 user = nobody
133 pm = dynamic
134 pm.max_children = 75
135 pm.start_servers = 10
136 pm.min_spare_servers = 5
137 pm.max_spare_servers = 20
138 pm.max_requests = 500
139 ''';
140 }
141 '';
142 description = ''
143 A mapping between PHP-FPM pool names and their configurations.
144 See the documentation on <literal>php-fpm.conf</literal> for
145 details on configuration directives. If no pools are defined,
146 the phpfpm service is disabled.
147 '';
148 };
149
150 pools = mkOption {
151 type = types.attrsOf (types.submodule (import ./pool-options.nix {
152 inherit lib;
153 }));
154 default = {};
155 example = literalExample ''
156 {
157 mypool = {
158 listen = "/path/to/unix/socket";
159 extraConfig = '''
160 user = nobody
161 pm = dynamic
162 pm.max_children = 75
163 pm.start_servers = 10
164 pm.min_spare_servers = 5
165 pm.max_spare_servers = 20
166 pm.max_requests = 500
167 ''';
168 }
169 }'';
170 description = ''
171 PHP-FPM pools. If no pools or poolConfigs are defined, the PHP-FPM
172 service is disabled.
173 '';
174 };
175 };
176 };
177
178 config = mkIf enabled {
179
180 systemd.slices.phpfpm = {
181 description = "PHP FastCGI Process manager pools slice";
182 };
183
184 systemd.targets.phpfpm = {
185 description = "PHP FastCGI Process manager pools target";
186 wantedBy = [ "multi-user.target" ];
187 };
188
189 systemd.services = flip mapAttrs' poolConfigs (pool: poolConfig:
190 nameValuePair "phpfpm-${pool}" {
191 description = "PHP FastCGI Process Manager service for pool ${pool}";
98163486
IB
192 after = [ "network.target" ] ++ (cfg.serviceDependencies.${pool} or []);
193 wants = cfg.serviceDependencies.${pool} or [];
98584540
IB
194 wantedBy = [ "phpfpm.target" ];
195 partOf = [ "phpfpm.target" ];
196 preStart = ''
197 mkdir -p ${stateDir}
8eded9ec 198 '' + (cfg.preStart.${pool} or "");
98584540
IB
199 serviceConfig = let
200 cfgFile = fpmCfgFile pool poolConfig;
201 poolPhpIni = cfg.poolPhpConfigs.${pool} or "";
202 in {
5f08b34c 203 EnvironmentFile = if builtins.hasAttr pool cfg.envFile then [cfg.envFile.${pool}] else [];
98584540
IB
204 Slice = "phpfpm.slice";
205 PrivateDevices = true;
206 ProtectSystem = "full";
207 ProtectHome = true;
208 # XXX: We need AF_NETLINK to make the sendmail SUID binary from postfix work
209 RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6 AF_NETLINK";
210 Type = "notify";
211 ExecStart = "${cfg.phpPackage}/bin/php-fpm -y ${cfgFile} -c ${phpIni poolPhpIni}";
212 ExecReload = "${pkgs.coreutils}/bin/kill -USR2 $MAINPID";
213 };
214 }
215 );
216 };
217}