gnu: datamash: Update to 1.1.1.
[jackhill/guix/guix.git] / gnu / services / web.scm
CommitLineData
58724c48
DT
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2015 David Thompson <davet@gnu.org>
dc72a7f7 3;;; Copyright © 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
6c12abbd 4;;; Copyright © 2016 ng0 <ng0@we.make.ritual.n0.is>
8c00b838 5;;; Copyright © 2016 Julien Lepiller <julien@lepiller.eu>
cb341293 6;;; Copyright © 2017 Christopher Baines <mail@cbaines.net>
58724c48
DT
7;;;
8;;; This file is part of GNU Guix.
9;;;
10;;; GNU Guix is free software; you can redistribute it and/or modify it
11;;; under the terms of the GNU General Public License as published by
12;;; the Free Software Foundation; either version 3 of the License, or (at
13;;; your option) any later version.
14;;;
15;;; GNU Guix is distributed in the hope that it will be useful, but
16;;; WITHOUT ANY WARRANTY; without even the implied warranty of
17;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;;; GNU General Public License for more details.
19;;;
20;;; You should have received a copy of the GNU General Public License
21;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
22
23(define-module (gnu services web)
24 #:use-module (gnu services)
0190c1c0 25 #:use-module (gnu services shepherd)
58724c48
DT
26 #:use-module (gnu system shadow)
27 #:use-module (gnu packages admin)
28 #:use-module (gnu packages web)
29 #:use-module (guix records)
58724c48 30 #:use-module (guix gexp)
d338237d 31 #:use-module (srfi srfi-1)
0adfe95a 32 #:use-module (ice-9 match)
24e96431
33 #:export (nginx-configuration
34 nginx-configuration?
3b9b12ef
JL
35 nginx-server-configuration
36 nginx-server-configuration?
cb341293
CB
37 nginx-upstream-configuration
38 nginx-upstream-configuration?
9c557a69
CB
39 nginx-location-configuration
40 nginx-location-configuration?
41 nginx-named-location-configuration
42 nginx-named-location-configuration?
24e96431
43 nginx-service
44 nginx-service-type))
58724c48
DT
45
46;;; Commentary:
47;;;
48;;; Web services.
49;;;
50;;; Code:
51
3b9b12ef
JL
52(define-record-type* <nginx-server-configuration>
53 nginx-server-configuration make-nginx-server-configuration
54 nginx-server-configuration?
55 (http-port nginx-server-configuration-http-port
8c00b838 56 (default 80))
3b9b12ef 57 (https-port nginx-server-configuration-https-port
8c00b838 58 (default 443))
3b9b12ef 59 (server-name nginx-server-configuration-server-name
8c00b838 60 (default (list 'default)))
3b9b12ef 61 (root nginx-server-configuration-root
8c00b838 62 (default "/srv/http"))
9c557a69
CB
63 (locations nginx-server-configuration-locations
64 (default '()))
3b9b12ef 65 (index nginx-server-configuration-index
8c00b838 66 (default (list "index.html")))
3b9b12ef 67 (ssl-certificate nginx-server-configuration-ssl-certificate
8c00b838 68 (default "/etc/nginx/cert.pem"))
3b9b12ef 69 (ssl-certificate-key nginx-server-configuration-ssl-certificate-key
8c00b838 70 (default "/etc/nginx/key.pem"))
3b9b12ef 71 (server-tokens? nginx-server-configuration-server-tokens?
8c00b838
JL
72 (default #f)))
73
cb341293
CB
74(define-record-type* <nginx-upstream-configuration>
75 nginx-upstream-configuration make-nginx-upstream-configuration
76 nginx-upstream-configuration?
77 (name nginx-upstream-configuration-name)
78 (servers nginx-upstream-configuration-servers))
79
9c557a69
CB
80(define-record-type* <nginx-location-configuration>
81 nginx-location-configuration make-nginx-location-configuration
82 nginx-location-configuration?
83 (uri nginx-location-configuration-uri
84 (default #f))
85 (body nginx-location-configuration-body))
86
87(define-record-type* <nginx-named-location-configuration>
88 nginx-named-location-configuration make-nginx-named-location-configuration
89 nginx-named-location-configuration?
90 (name nginx-named-location-configuration-name
91 (default #f))
92 (body nginx-named-location-configuration-body))
93
0adfe95a
LC
94(define-record-type* <nginx-configuration>
95 nginx-configuration make-nginx-configuration
96 nginx-configuration?
dc72a7f7
LC
97 (nginx nginx-configuration-nginx ;<package>
98 (default nginx))
99 (log-directory nginx-configuration-log-directory ;string
100 (default "/var/log/nginx"))
101 (run-directory nginx-configuration-run-directory ;string
102 (default "/var/run/nginx"))
103 (server-blocks nginx-configuration-server-blocks
104 (default '())) ;list of <nginx-server-configuration>
105 (upstream-blocks nginx-configuration-upstream-blocks
106 (default '())) ;list of <nginx-upstream-configuration>
107 (file nginx-configuration-file ;#f | string | file-like
108 (default #f)))
0adfe95a 109
8c00b838
JL
110(define (config-domain-strings names)
111 "Return a string denoting the nginx config representation of NAMES, a list
112of domain names."
819c1945 113 (string-join
8c00b838 114 (map (match-lambda
4e9ae301
JL
115 ('default "_ ")
116 ((? string? str) (string-append str " ")))
8c00b838
JL
117 names)))
118
119(define (config-index-strings names)
120 "Return a string denoting the nginx config representation of NAMES, a list
121of index files."
819c1945 122 (string-join
8c00b838 123 (map (match-lambda
4e9ae301 124 ((? string? str) (string-append str " ")))
8c00b838
JL
125 names)))
126
9c557a69
CB
127(define nginx-location-config
128 (match-lambda
129 (($ <nginx-location-configuration> uri body)
130 (string-append
131 " location " uri " {\n"
132 " " (string-join body "\n ") "\n"
133 " }\n"))
134 (($ <nginx-named-location-configuration> name body)
135 (string-append
136 " location @" name " {\n"
137 " " (string-join body "\n ") "\n"
138 " }\n"))))
139
3b9b12ef 140(define (default-nginx-server-config server)
8c00b838
JL
141 (string-append
142 " server {\n"
3b9b12ef 143 (if (nginx-server-configuration-http-port server)
8c00b838 144 (string-append " listen "
3b9b12ef 145 (number->string (nginx-server-configuration-http-port server))
8c00b838
JL
146 ";\n")
147 "")
3b9b12ef 148 (if (nginx-server-configuration-https-port server)
8c00b838 149 (string-append " listen "
3b9b12ef 150 (number->string (nginx-server-configuration-https-port server))
8c00b838
JL
151 " ssl;\n")
152 "")
153 " server_name " (config-domain-strings
3b9b12ef 154 (nginx-server-configuration-server-name server))
8c00b838 155 ";\n"
3b9b12ef 156 (if (nginx-server-configuration-ssl-certificate server)
8c00b838 157 (string-append " ssl_certificate "
3b9b12ef 158 (nginx-server-configuration-ssl-certificate server) ";\n")
8c00b838 159 "")
3b9b12ef 160 (if (nginx-server-configuration-ssl-certificate-key server)
8c00b838 161 (string-append " ssl_certificate_key "
3b9b12ef 162 (nginx-server-configuration-ssl-certificate-key server) ";\n")
8c00b838 163 "")
3b9b12ef
JL
164 " root " (nginx-server-configuration-root server) ";\n"
165 " index " (config-index-strings (nginx-server-configuration-index server)) ";\n"
166 " server_tokens " (if (nginx-server-configuration-server-tokens? server)
8c00b838 167 "on" "off") ";\n"
9c557a69
CB
168 "\n"
169 (string-join
170 (map nginx-location-config (nginx-server-configuration-locations server))
171 "\n")
172 " }\n"))
cb341293
CB
173
174(define (nginx-upstream-config upstream)
175 (string-append
176 " upstream " (nginx-upstream-configuration-name upstream) " {\n"
177 (string-concatenate
178 (map (lambda (server)
179 (simple-format #f " server ~A;\n" server))
180 (nginx-upstream-configuration-servers upstream)))
8c00b838
JL
181 " }\n"))
182
cb341293
CB
183(define (default-nginx-config log-directory run-directory server-list upstream-list)
184 (mixed-text-file "nginx.conf"
58724c48
DT
185 "user nginx nginx;\n"
186 "pid " run-directory "/pid;\n"
187 "error_log " log-directory "/error.log info;\n"
188 "http {\n"
8c00b838
JL
189 " client_body_temp_path " run-directory "/client_body_temp;\n"
190 " proxy_temp_path " run-directory "/proxy_temp;\n"
191 " fastcgi_temp_path " run-directory "/fastcgi_temp;\n"
192 " uwsgi_temp_path " run-directory "/uwsgi_temp;\n"
193 " scgi_temp_path " run-directory "/scgi_temp;\n"
58724c48 194 " access_log " log-directory "/access.log;\n"
cb341293
CB
195 "\n"
196 (string-join
197 (filter (lambda (section) (not (null? section)))
198 (map nginx-upstream-config upstream-list))
199 "\n")
200 "\n"
3b9b12ef 201 (let ((http (map default-nginx-server-config server-list)))
8c00b838
JL
202 (do ((http http (cdr http))
203 (block "" (string-append (car http) "\n" block )))
204 ((null? http) block)))
58724c48 205 "}\n"
cb341293 206 "events {}\n"))
58724c48 207
0adfe95a
LC
208(define %nginx-accounts
209 (list (user-group (name "nginx") (system? #t))
210 (user-account
211 (name "nginx")
212 (group "nginx")
213 (system? #t)
214 (comment "nginx server user")
215 (home-directory "/var/empty")
9e41130b 216 (shell (file-append shadow "/sbin/nologin")))))
0adfe95a
LC
217
218(define nginx-activation
219 (match-lambda
d338237d 220 (($ <nginx-configuration> nginx log-directory run-directory server-blocks
cb341293 221 upstream-blocks config-file)
0adfe95a
LC
222 #~(begin
223 (use-modules (guix build utils))
224
225 (format #t "creating nginx log directory '~a'~%" #$log-directory)
226 (mkdir-p #$log-directory)
227 (format #t "creating nginx run directory '~a'~%" #$run-directory)
228 (mkdir-p #$run-directory)
8c00b838
JL
229 (format #t "creating nginx temp directories '~a/{client_body,proxy,fastcgi,uwsgi,scgi}_temp'~%" #$run-directory)
230 (mkdir-p (string-append #$run-directory "/client_body_temp"))
231 (mkdir-p (string-append #$run-directory "/proxy_temp"))
232 (mkdir-p (string-append #$run-directory "/fastcgi_temp"))
233 (mkdir-p (string-append #$run-directory "/uwsgi_temp"))
234 (mkdir-p (string-append #$run-directory "/scgi_temp"))
0adfe95a 235 ;; Check configuration file syntax.
d21047d5 236 (system* (string-append #$nginx "/sbin/nginx")
d338237d
JL
237 "-c" #$(or config-file
238 (default-nginx-config log-directory
cb341293 239 run-directory server-blocks upstream-blocks))
d338237d 240 "-t")))))
0adfe95a 241
d4053c71 242(define nginx-shepherd-service
0adfe95a 243 (match-lambda
d338237d 244 (($ <nginx-configuration> nginx log-directory run-directory server-blocks
cb341293 245 upstream-blocks config-file)
9e41130b 246 (let* ((nginx-binary (file-append nginx "/sbin/nginx"))
0adfe95a
LC
247 (nginx-action
248 (lambda args
249 #~(lambda _
250 (zero?
d338237d
JL
251 (system* #$nginx-binary "-c"
252 #$(or config-file
253 (default-nginx-config log-directory
cb341293 254 run-directory server-blocks upstream-blocks))
d338237d 255 #$@args))))))
0adfe95a
LC
256
257 ;; TODO: Add 'reload' action.
d4053c71 258 (list (shepherd-service
0adfe95a
LC
259 (provision '(nginx))
260 (documentation "Run the nginx daemon.")
261 (requirement '(user-processes loopback))
262 (start (nginx-action "-p" run-directory))
263 (stop (nginx-action "-s" "stop"))))))))
264
265(define nginx-service-type
266 (service-type (name 'nginx)
267 (extensions
d4053c71
AK
268 (list (service-extension shepherd-root-service-type
269 nginx-shepherd-service)
0adfe95a
LC
270 (service-extension activation-service-type
271 nginx-activation)
272 (service-extension account-service-type
d338237d
JL
273 (const %nginx-accounts))))
274 (compose concatenate)
275 (extend (lambda (config servers)
276 (nginx-configuration
277 (inherit config)
278 (server-blocks
279 (append (nginx-configuration-server-blocks config)
280 servers)))))))
0adfe95a 281
58724c48
DT
282(define* (nginx-service #:key (nginx nginx)
283 (log-directory "/var/log/nginx")
284 (run-directory "/var/run/nginx")
d338237d 285 (server-list '())
cb341293 286 (upstream-list '())
d338237d 287 (config-file #f))
58724c48
DT
288 "Return a service that runs NGINX, the nginx web server.
289
6c12abbd 290The nginx daemon loads its runtime configuration from CONFIG-FILE, stores log
58724c48 291files in LOG-DIRECTORY, and stores temporary runtime files in RUN-DIRECTORY."
0adfe95a
LC
292 (service nginx-service-type
293 (nginx-configuration
294 (nginx nginx)
295 (log-directory log-directory)
296 (run-directory run-directory)
d338237d 297 (server-blocks server-list)
cb341293 298 (upstream-blocks upstream-list)
0adfe95a 299 (file config-file))))