summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modules/default.nix1
-rw-r--r--modules/websites/php-application.nix152
2 files changed, 153 insertions, 0 deletions
diff --git a/modules/default.nix b/modules/default.nix
index e36f1a06..dd348702 100644
--- a/modules/default.nix
+++ b/modules/default.nix
@@ -10,5 +10,6 @@
10 mediagoblin = ./webapps/mediagoblin.nix; 10 mediagoblin = ./webapps/mediagoblin.nix;
11 peertube = ./webapps/peertube.nix; 11 peertube = ./webapps/peertube.nix;
12 12
13 php-application = ./websites/php-application.nix;
13 websites = ./websites; 14 websites = ./websites;
14} // (if builtins.pathExists ./private then import ./private else {}) 15} // (if builtins.pathExists ./private then import ./private else {})
diff --git a/modules/websites/php-application.nix b/modules/websites/php-application.nix
new file mode 100644
index 00000000..7bbae50a
--- /dev/null
+++ b/modules/websites/php-application.nix
@@ -0,0 +1,152 @@
1{ lib, config, ... }:
2with lib;
3let
4 cfg = config.services.phpApplication;
5 cfgByEnv = lists.groupBy (x: x.websiteEnv) (builtins.attrValues cfg);
6in
7{
8 options = {
9 services.phpApplication = with types; mkOption {
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 };
22 mode = mkOption {
23 type = str;
24 default = "0700";
25 description = ''
26 Mode to apply to the vardir
27 '';
28 };
29 phpSession = mkOption {
30 type = bool;
31 default = true;
32 description = "Handle phpsession files separately in vardir";
33 };
34 websiteEnv = mkOption {
35 type = str;
36 description = ''
37 website instance name to use
38 '';
39 };
40 httpdUser = mkOption {
41 type = str;
42 default = config.services.httpd.user;
43 description = ''
44 httpd user to run the prestart scripts as.
45 '';
46 };
47 httpdGroup = mkOption {
48 type = str;
49 default = config.services.httpd.group;
50 description = ''
51 httpd group to run the prestart scripts as.
52 '';
53 };
54 app = mkOption {
55 type = path;
56 description = ''
57 Path to application root
58 '';
59 };
60 webappName = mkOption {
61 type = nullOr str;
62 description = ''
63 Alias name for the app, to be used in services.websites.webappDirs
64 '';
65 };
66 webRoot = mkOption {
67 type = nullOr path;
68 description = ''
69 Path to the web root path of the application. May differ from the application itself (usually a subdirectory)
70 '';
71 };
72 preStartActions = mkOption {
73 type = listOf str;
74 default = [];
75 description = ''
76 List of actions to run as apache user at preStart when
77 whatchFiles or app dir changed.
78 '';
79 };
80 serviceDeps = mkOption {
81 type = listOf str;
82 default = [];
83 description = ''
84 List of systemd services this application depends on
85 '';
86 };
87 watchFiles = mkOption {
88 type = listOf path;
89 default = [];
90 description = ''
91 Path to other files to watch to trigger preStart scripts
92 '';
93 };
94 };
95 });
96 };
97 };
98
99 config = {
100 services.websites = attrsets.mapAttrs' (name: cfgs: attrsets.nameValuePair
101 name {
102 modules = [ "proxy_fcgi" ];
103 watchPaths = builtins.concatLists (map (c: c.watchFiles) cfgs);
104 }
105 ) cfgByEnv;
106
107 services.websitesWebappDirs = attrsets.mapAttrs' (name: icfg: attrsets.nameValuePair
108 icfg.webappName icfg.webRoot
109 ) (attrsets.filterAttrs (n: v: !isNull v.webappName && !isNull v.webRoot) cfg);
110
111 systemd.services = attrsets.mapAttrs' (name: icfg: attrsets.nameValuePair
112 "phpfpm-${name}" {
113 after = lib.mkAfter icfg.serviceDeps;
114 wants = icfg.serviceDeps;
115 preStart = lib.mkAfter (optionalString (!isNull icfg.varDir) ''
116 watchFilesChanged() {
117 ${optionalString (builtins.length icfg.watchFiles == 0) "return 0"}
118 [ ! -f "${icfg.varDir}"/watchedFiles ] \
119 || ! sha512sum -c --status ${icfg.varDir}/watchedFiles
120 }
121 appDirChanged() {
122 [ ! -f "${icfg.varDir}/currentWebappDir" -o \
123 "${icfg.app}" != "$(cat ${icfg.varDir}/currentWebappDir 2>/dev/null)" ]
124 }
125 updateWatchFiles() {
126 ${optionalString (builtins.length icfg.watchFiles == 0) "return 0"}
127 sha512sum ${builtins.concatStringsSep " " icfg.watchFiles} > ${icfg.varDir}/watchedFiles
128 }
129
130 if watchFilesChanged || appDirChanged; then
131 pushd ${icfg.app} > /dev/null
132 ${builtins.concatStringsSep "\n " (map (c: "/run/wrappers/bin/sudo -u ${icfg.httpdUser} ${c}") icfg.preStartActions) }
133 popd > /dev/null
134 echo -n "${icfg.app}" > ${icfg.varDir}/currentWebappDir
135 updateWatchFiles
136 fi
137 '');
138 }
139 ) cfg;
140
141 system.activationScripts = attrsets.mapAttrs' (name: icfg: attrsets.nameValuePair
142 name {
143 deps = [];
144 text = optionalString (!isNull icfg.varDir) ''
145 install -m ${icfg.mode} -o ${icfg.httpdUser} -g ${icfg.httpdGroup} -d ${icfg.varDir}
146 '' + optionalString (icfg.phpSession) ''
147 install -m 0700 -o ${icfg.httpdUser} -g ${icfg.httpdGroup} -d ${icfg.varDir}/phpSessions
148 '';
149 }
150 ) cfg;
151 };
152}