diff options
-rw-r--r-- | modules/default.nix | 1 | ||||
-rw-r--r-- | modules/websites/php-application.nix | 152 |
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, ... }: | ||
2 | with lib; | ||
3 | let | ||
4 | cfg = config.services.phpApplication; | ||
5 | cfgByEnv = lists.groupBy (x: x.websiteEnv) (builtins.attrValues cfg); | ||
6 | in | ||
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 | } | ||