]> git.immae.eu Git - perso/Immae/Config/Nix.git/blame - modules/websites/php-application.nix
Remove webappdirs
[perso/Immae/Config/Nix.git] / modules / websites / php-application.nix
CommitLineData
dcac3ec7 1{ lib, config, pkgs, ... }:
2e48907d
IB
2with lib;
3let
4 cfg = config.services.phpApplication;
717ccfd9 5 cfgByEnv = lists.groupBy (x: x.websiteEnv) (builtins.attrValues cfg.apps);
2e48907d
IB
6in
7{
717ccfd9
IB
8 options = with types; {
9 services.phpApplication.apps = mkOption {
2e48907d
IB
10 default = {};
11 description = ''
12 php applications to define
13 '';
14 type = attrsOf (submodule {
15 options = {
16 varDir = mkOption {
17 type = nullOr path;
18 description = ''
19 Path to application’s vardir.
20 '';
21 };
1594c8da
IB
22 varDirPaths = mkOption {
23 type = attrsOf str;
24 default = {};
25 description = ''
26 Map of additional folders => mode to create under varDir
27 '';
28 };
2e48907d
IB
29 mode = mkOption {
30 type = str;
31 default = "0700";
32 description = ''
33 Mode to apply to the vardir
34 '';
35 };
36 phpSession = mkOption {
37 type = bool;
38 default = true;
39 description = "Handle phpsession files separately in vardir";
40 };
717ccfd9
IB
41 phpListen = mkOption {
42 type = nullOr str;
43 default = null;
44 description = "Name of the socket to listen to. Defaults to app name if null";
45 };
46 phpPool = mkOption {
5400b9b6
IB
47 type = attrsOf str;
48 default = {};
717ccfd9
IB
49 description = "Pool configuration to append";
50 };
5400b9b6
IB
51 phpEnv = mkOption {
52 type = attrsOf str;
53 default = {};
54 description = "Pool environment to append";
55 };
dcac3ec7
IB
56 phpPackage = mkOption {
57 type = attrsOf str;
58 default = pkgs.php;
59 description = "Php package to use";
60 };
717ccfd9
IB
61 phpOptions = mkOption {
62 type = lines;
63 default = "";
64 description = "php configuration to append";
65 };
66 phpOpenbasedir = mkOption {
67 type = listOf path;
68 default = [];
69 description = ''
70 paths to add to php open_basedir configuration in addition to app and vardir
71 '';
72 };
73 phpWatchFiles = mkOption {
74 type = listOf path;
75 default = [];
76 description = ''
77 Path to other files to watch to trigger preStart scripts
78 '';
79 };
2e48907d
IB
80 websiteEnv = mkOption {
81 type = str;
82 description = ''
83 website instance name to use
84 '';
85 };
86 httpdUser = mkOption {
87 type = str;
88 default = config.services.httpd.user;
89 description = ''
90 httpd user to run the prestart scripts as.
91 '';
92 };
93 httpdGroup = mkOption {
94 type = str;
95 default = config.services.httpd.group;
96 description = ''
97 httpd group to run the prestart scripts as.
98 '';
99 };
717ccfd9
IB
100 httpdWatchFiles = mkOption {
101 type = listOf path;
102 default = [];
103 description = ''
104 Path to other files to watch to trigger httpd reload
105 '';
106 };
2e48907d
IB
107 app = mkOption {
108 type = path;
109 description = ''
110 Path to application root
111 '';
112 };
2e48907d
IB
113 webRoot = mkOption {
114 type = nullOr path;
115 description = ''
116 Path to the web root path of the application. May differ from the application itself (usually a subdirectory)
117 '';
118 };
119 preStartActions = mkOption {
120 type = listOf str;
121 default = [];
122 description = ''
123 List of actions to run as apache user at preStart when
124 whatchFiles or app dir changed.
125 '';
126 };
127 serviceDeps = mkOption {
128 type = listOf str;
129 default = [];
130 description = ''
131 List of systemd services this application depends on
132 '';
133 };
2e48907d
IB
134 };
135 });
136 };
717ccfd9
IB
137 # Read-only variables
138 services.phpApplication.phpListenPaths = mkOption {
139 type = attrsOf path;
140 default = attrsets.mapAttrs' (name: icfg: attrsets.nameValuePair
5400b9b6 141 name config.services.phpfpm.pools."${name}".socket
717ccfd9
IB
142 ) cfg.apps;
143 readOnly = true;
144 description = ''
145 Full paths to listen for php
146 '';
147 };
2e48907d
IB
148 };
149
150 config = {
29f8cb85 151 services.websites.env = attrsets.mapAttrs' (name: cfgs: attrsets.nameValuePair
2e48907d
IB
152 name {
153 modules = [ "proxy_fcgi" ];
717ccfd9 154 watchPaths = builtins.concatLists (map (c: c.httpdWatchFiles) cfgs);
2e48907d
IB
155 }
156 ) cfgByEnv;
157
717ccfd9
IB
158 services.phpfpm.pools = attrsets.mapAttrs' (name: icfg: attrsets.nameValuePair
159 name {
5400b9b6
IB
160 user = icfg.httpdUser;
161 group = icfg.httpdUser;
162 settings = {
163 "listen.owner" = icfg.httpdUser;
164 "listen.group" = icfg.httpdGroup;
165 "php_admin_value[open_basedir]" = builtins.concatStringsSep ":" ([icfg.app icfg.varDir] ++ icfg.phpWatchFiles ++ icfg.phpOpenbasedir);
166 }
167 // optionalAttrs (icfg.phpSession) { "php_admin_value[session.save_path]" = "${icfg.varDir}/phpSessions"; }
168 // icfg.phpPool;
717ccfd9 169 phpOptions = config.services.phpfpm.phpOptions + icfg.phpOptions;
dcac3ec7 170 inherit (icfg) phpEnv phpPackage;
717ccfd9
IB
171 }
172 ) cfg.apps;
173
1594c8da
IB
174 services.filesWatcher = attrsets.mapAttrs' (name: icfg: attrsets.nameValuePair
175 "phpfpm-${name}" {
176 restart = true;
177 paths = icfg.phpWatchFiles;
178 }
179 ) (attrsets.filterAttrs (n: v: builtins.length v.phpWatchFiles > 0) cfg.apps);
180
2e48907d
IB
181 systemd.services = attrsets.mapAttrs' (name: icfg: attrsets.nameValuePair
182 "phpfpm-${name}" {
183 after = lib.mkAfter icfg.serviceDeps;
184 wants = icfg.serviceDeps;
185 preStart = lib.mkAfter (optionalString (!isNull icfg.varDir) ''
186 watchFilesChanged() {
717ccfd9 187 ${optionalString (builtins.length icfg.phpWatchFiles == 0) "return 1"}
2e48907d
IB
188 [ ! -f "${icfg.varDir}"/watchedFiles ] \
189 || ! sha512sum -c --status ${icfg.varDir}/watchedFiles
190 }
191 appDirChanged() {
192 [ ! -f "${icfg.varDir}/currentWebappDir" -o \
193 "${icfg.app}" != "$(cat ${icfg.varDir}/currentWebappDir 2>/dev/null)" ]
194 }
195 updateWatchFiles() {
717ccfd9
IB
196 ${optionalString (builtins.length icfg.phpWatchFiles == 0) "return 0"}
197 sha512sum ${builtins.concatStringsSep " " icfg.phpWatchFiles} > ${icfg.varDir}/watchedFiles
2e48907d
IB
198 }
199
200 if watchFilesChanged || appDirChanged; then
201 pushd ${icfg.app} > /dev/null
202 ${builtins.concatStringsSep "\n " (map (c: "/run/wrappers/bin/sudo -u ${icfg.httpdUser} ${c}") icfg.preStartActions) }
203 popd > /dev/null
204 echo -n "${icfg.app}" > ${icfg.varDir}/currentWebappDir
205 updateWatchFiles
206 fi
207 '');
208 }
717ccfd9 209 ) cfg.apps;
2e48907d
IB
210
211 system.activationScripts = attrsets.mapAttrs' (name: icfg: attrsets.nameValuePair
212 name {
213 deps = [];
214 text = optionalString (!isNull icfg.varDir) ''
215 install -m ${icfg.mode} -o ${icfg.httpdUser} -g ${icfg.httpdGroup} -d ${icfg.varDir}
216 '' + optionalString (icfg.phpSession) ''
217 install -m 0700 -o ${icfg.httpdUser} -g ${icfg.httpdGroup} -d ${icfg.varDir}/phpSessions
1594c8da
IB
218 '' + builtins.concatStringsSep "\n" (attrsets.mapAttrsToList (n: v: ''
219 install -m ${v} -o ${icfg.httpdUser} -g ${icfg.httpdGroup} -d ${icfg.varDir}/${n}
220 '') icfg.varDirPaths);
2e48907d 221 }
717ccfd9 222 ) cfg.apps;
2e48907d
IB
223 };
224}