1 { lib, config, pkgs, ... }:
4 cfg = config.services.phpApplication;
5 cfgByEnv = lists.groupBy (x: x.websiteEnv) (builtins.attrValues cfg.apps);
8 options = with types; {
9 services.phpApplication.apps = mkOption {
12 php applications to define
14 type = attrsOf (submodule {
19 Path to application’s vardir.
22 varDirPaths = mkOption {
26 Map of additional folders => mode to create under varDir
33 Mode to apply to the vardir
36 phpSession = mkOption {
39 description = "Handle phpsession files separately in vardir";
41 phpListen = mkOption {
44 description = "Name of the socket to listen to. Defaults to app name if null";
49 description = "Pool configuration to append";
54 description = "Pool environment to append";
56 phpPackage = mkOption {
59 description = "Php package to use";
61 phpOptions = mkOption {
64 description = "php configuration to append";
66 phpOpenbasedir = mkOption {
70 paths to add to php open_basedir configuration in addition to app and vardir
73 phpWatchFiles = mkOption {
77 Path to other files to watch to trigger preStart scripts
80 websiteEnv = mkOption {
83 website instance name to use
86 httpdUser = mkOption {
88 default = config.services.httpd.user;
90 httpd user to run the prestart scripts as.
93 httpdGroup = mkOption {
95 default = config.services.httpd.group;
97 httpd group to run the prestart scripts as.
100 httpdWatchFiles = mkOption {
104 Path to other files to watch to trigger httpd reload
110 Path to application root
116 Path to the web root path of the application. May differ from the application itself (usually a subdirectory)
119 preStartActions = mkOption {
123 List of actions to run as apache user at preStart when
124 whatchFiles or app dir changed.
127 serviceDeps = mkOption {
131 List of systemd services this application depends on
137 # Read-only variables
138 services.phpApplication.phpListenPaths = mkOption {
140 default = attrsets.mapAttrs' (name: icfg: attrsets.nameValuePair
141 name config.services.phpfpm.pools."${name}".socket
145 Full paths to listen for php
151 services.websites.env = attrsets.mapAttrs' (name: cfgs: attrsets.nameValuePair
153 modules = [ "proxy_fcgi" ];
154 watchPaths = builtins.concatLists (map (c: c.httpdWatchFiles) cfgs);
158 services.phpfpm.pools = attrsets.mapAttrs' (name: icfg: attrsets.nameValuePair
160 user = icfg.httpdUser;
161 group = icfg.httpdUser;
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);
167 // optionalAttrs (icfg.phpSession) { "php_admin_value[session.save_path]" = "${icfg.varDir}/phpSessions"; }
169 phpOptions = config.services.phpfpm.phpOptions + icfg.phpOptions;
170 inherit (icfg) phpEnv phpPackage;
174 services.filesWatcher = attrsets.mapAttrs' (name: icfg: attrsets.nameValuePair
177 paths = icfg.phpWatchFiles;
179 ) (attrsets.filterAttrs (n: v: builtins.length v.phpWatchFiles > 0) cfg.apps);
181 systemd.services = attrsets.mapAttrs' (name: icfg: attrsets.nameValuePair
183 after = lib.mkAfter icfg.serviceDeps;
184 wants = icfg.serviceDeps;
185 preStart = lib.mkAfter (optionalString (!isNull icfg.varDir) ''
186 watchFilesChanged() {
187 ${optionalString (builtins.length icfg.phpWatchFiles == 0) "return 1"}
188 [ ! -f "${icfg.varDir}"/watchedFiles ] \
189 || ! sha512sum -c --status ${icfg.varDir}/watchedFiles
192 [ ! -f "${icfg.varDir}/currentWebappDir" -o \
193 "${icfg.app}" != "$(cat ${icfg.varDir}/currentWebappDir 2>/dev/null)" ]
196 ${optionalString (builtins.length icfg.phpWatchFiles == 0) "return 0"}
197 sha512sum ${builtins.concatStringsSep " " icfg.phpWatchFiles} > ${icfg.varDir}/watchedFiles
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) }
204 echo -n "${icfg.app}" > ${icfg.varDir}/currentWebappDir
211 system.activationScripts = attrsets.mapAttrs' (name: icfg: attrsets.nameValuePair
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
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);