--- /dev/null
+{ lib, config, ... }:
+with lib;
+let
+ cfg = config.services.phpApplication;
+ cfgByEnv = lists.groupBy (x: x.websiteEnv) (builtins.attrValues cfg);
+in
+{
+ options = {
+ services.phpApplication = with types; mkOption {
+ default = {};
+ description = ''
+ php applications to define
+ '';
+ type = attrsOf (submodule {
+ options = {
+ varDir = mkOption {
+ type = nullOr path;
+ description = ''
+ Path to application’s vardir.
+ '';
+ };
+ mode = mkOption {
+ type = str;
+ default = "0700";
+ description = ''
+ Mode to apply to the vardir
+ '';
+ };
+ phpSession = mkOption {
+ type = bool;
+ default = true;
+ description = "Handle phpsession files separately in vardir";
+ };
+ websiteEnv = mkOption {
+ type = str;
+ description = ''
+ website instance name to use
+ '';
+ };
+ httpdUser = mkOption {
+ type = str;
+ default = config.services.httpd.user;
+ description = ''
+ httpd user to run the prestart scripts as.
+ '';
+ };
+ httpdGroup = mkOption {
+ type = str;
+ default = config.services.httpd.group;
+ description = ''
+ httpd group to run the prestart scripts as.
+ '';
+ };
+ app = mkOption {
+ type = path;
+ description = ''
+ Path to application root
+ '';
+ };
+ webappName = mkOption {
+ type = nullOr str;
+ description = ''
+ Alias name for the app, to be used in services.websites.webappDirs
+ '';
+ };
+ webRoot = mkOption {
+ type = nullOr path;
+ description = ''
+ Path to the web root path of the application. May differ from the application itself (usually a subdirectory)
+ '';
+ };
+ preStartActions = mkOption {
+ type = listOf str;
+ default = [];
+ description = ''
+ List of actions to run as apache user at preStart when
+ whatchFiles or app dir changed.
+ '';
+ };
+ serviceDeps = mkOption {
+ type = listOf str;
+ default = [];
+ description = ''
+ List of systemd services this application depends on
+ '';
+ };
+ watchFiles = mkOption {
+ type = listOf path;
+ default = [];
+ description = ''
+ Path to other files to watch to trigger preStart scripts
+ '';
+ };
+ };
+ });
+ };
+ };
+
+ config = {
+ services.websites = attrsets.mapAttrs' (name: cfgs: attrsets.nameValuePair
+ name {
+ modules = [ "proxy_fcgi" ];
+ watchPaths = builtins.concatLists (map (c: c.watchFiles) cfgs);
+ }
+ ) cfgByEnv;
+
+ services.websitesWebappDirs = attrsets.mapAttrs' (name: icfg: attrsets.nameValuePair
+ icfg.webappName icfg.webRoot
+ ) (attrsets.filterAttrs (n: v: !isNull v.webappName && !isNull v.webRoot) cfg);
+
+ systemd.services = attrsets.mapAttrs' (name: icfg: attrsets.nameValuePair
+ "phpfpm-${name}" {
+ after = lib.mkAfter icfg.serviceDeps;
+ wants = icfg.serviceDeps;
+ preStart = lib.mkAfter (optionalString (!isNull icfg.varDir) ''
+ watchFilesChanged() {
+ ${optionalString (builtins.length icfg.watchFiles == 0) "return 0"}
+ [ ! -f "${icfg.varDir}"/watchedFiles ] \
+ || ! sha512sum -c --status ${icfg.varDir}/watchedFiles
+ }
+ appDirChanged() {
+ [ ! -f "${icfg.varDir}/currentWebappDir" -o \
+ "${icfg.app}" != "$(cat ${icfg.varDir}/currentWebappDir 2>/dev/null)" ]
+ }
+ updateWatchFiles() {
+ ${optionalString (builtins.length icfg.watchFiles == 0) "return 0"}
+ sha512sum ${builtins.concatStringsSep " " icfg.watchFiles} > ${icfg.varDir}/watchedFiles
+ }
+
+ if watchFilesChanged || appDirChanged; then
+ pushd ${icfg.app} > /dev/null
+ ${builtins.concatStringsSep "\n " (map (c: "/run/wrappers/bin/sudo -u ${icfg.httpdUser} ${c}") icfg.preStartActions) }
+ popd > /dev/null
+ echo -n "${icfg.app}" > ${icfg.varDir}/currentWebappDir
+ updateWatchFiles
+ fi
+ '');
+ }
+ ) cfg;
+
+ system.activationScripts = attrsets.mapAttrs' (name: icfg: attrsets.nameValuePair
+ name {
+ deps = [];
+ text = optionalString (!isNull icfg.varDir) ''
+ install -m ${icfg.mode} -o ${icfg.httpdUser} -g ${icfg.httpdGroup} -d ${icfg.varDir}
+ '' + optionalString (icfg.phpSession) ''
+ install -m 0700 -o ${icfg.httpdUser} -g ${icfg.httpdGroup} -d ${icfg.varDir}/phpSessions
+ '';
+ }
+ ) cfg;
+ };
+}