services: virtual-terminal: Write to "default_utf8" only if necessary.
[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>
81317071 3;;; Copyright © 2015, 2016, 2017, 2018 Ludovic Courtès <ludo@gnu.org>
4a78fd46 4;;; Copyright © 2016 Nils Gillmann <ng0@n0.is>
08da664d 5;;; Copyright © 2016, 2017, 2018 Julien Lepiller <julien@lepiller.eu>
cb341293 6;;; Copyright © 2017 Christopher Baines <mail@cbaines.net>
64bae723 7;;; Copyright © 2017 nee <nee-git@hidamari.blue>
4ae0607d 8;;; Copyright © 2017, 2018 Clément Lassieur <clement@lassieur.org>
93b83eb3 9;;; Copyright © 2018 Pierre-Antoine Rouby <pierre-antoine.rouby@inria.fr>
19de8273 10;;; Copyright © 2017 Christopher Baines <mail@cbaines.net>
3b97a177 11;;; Copyright © 2018 Marius Bakke <mbakke@fastmail.com>
58724c48
DT
12;;;
13;;; This file is part of GNU Guix.
14;;;
15;;; GNU Guix is free software; you can redistribute it and/or modify it
16;;; under the terms of the GNU General Public License as published by
17;;; the Free Software Foundation; either version 3 of the License, or (at
18;;; your option) any later version.
19;;;
20;;; GNU Guix is distributed in the hope that it will be useful, but
21;;; WITHOUT ANY WARRANTY; without even the implied warranty of
22;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23;;; GNU General Public License for more details.
24;;;
25;;; You should have received a copy of the GNU General Public License
26;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
27
28(define-module (gnu services web)
29 #:use-module (gnu services)
0190c1c0 30 #:use-module (gnu services shepherd)
81317071 31 #:use-module (gnu services admin)
93b83eb3 32 #:use-module (gnu system pam)
58724c48
DT
33 #:use-module (gnu system shadow)
34 #:use-module (gnu packages admin)
35 #:use-module (gnu packages web)
64bae723 36 #:use-module (gnu packages php)
93b83eb3 37 #:use-module (gnu packages guile)
19de8273 38 #:use-module (gnu packages logging)
58724c48 39 #:use-module (guix records)
93b83eb3 40 #:use-module (guix modules)
58724c48 41 #:use-module (guix gexp)
19de8273 42 #:use-module ((guix store) #:select (text-file))
64bae723 43 #:use-module ((guix utils) #:select (version-major))
44 #:use-module ((guix packages) #:select (package-version))
d338237d 45 #:use-module (srfi srfi-1)
d067e4ba 46 #:use-module (srfi srfi-9)
0adfe95a 47 #:use-module (ice-9 match)
d067e4ba
CB
48 #:export (<httpd-configuration>
49 httpd-configuration
50 httpd-configuration?
51 httpd-configuration-package
52 httpd-configuration-pid-file
53 httpd-configuration-config
54
55 <httpd-virtualhost>
56 httpd-virtualhost
57 httpd-virtualhost?
58 httpd-virtualhost-addresses-and-ports
59 httpd-virtualhost-contents
60
61 <httpd-config-file>
62 httpd-config-file
63 httpd-config-file?
64 httpd-config-file-modules
65 httpd-config-file-server-root
66 httpd-config-file-server-name
67 httpd-config-file-listen
68 httpd-config-file-pid-file
69 httpd-config-file-error-log
70 httpd-config-file-user
71 httpd-config-file-group
72
73 httpd-service-type
74
75 <nginx-configuration>
e4b729f8 76 nginx-configuration
24e96431 77 nginx-configuration?
e4b729f8
CB
78 nginx-configuartion-nginx
79 nginx-configuration-log-directory
80 nginx-configuration-run-directory
81 nginx-configuration-server-blocks
82 nginx-configuration-upstream-blocks
2881f852
CB
83 nginx-configuration-server-names-hash-bucket-size
84 nginx-configuration-server-names-hash-bucket-max-size
25e071ea 85 nginx-configuration-extra-content
e4b729f8
CB
86 nginx-configuration-file
87
88 <nginx-server-configuration>
3b9b12ef
JL
89 nginx-server-configuration
90 nginx-server-configuration?
8b223cea 91 nginx-server-configuration-listen
e4b729f8
CB
92 nginx-server-configuration-server-name
93 nginx-server-configuration-root
94 nginx-server-configuration-locations
95 nginx-server-configuration-index
96 nginx-server-configuration-ssl-certificate
97 nginx-server-configuration-ssl-certificate-key
98 nginx-server-configuration-server-tokens?
b05e8ee1 99 nginx-server-configuration-raw-content
e4b729f8
CB
100
101 <nginx-upstream-configuration>
cb341293
CB
102 nginx-upstream-configuration
103 nginx-upstream-configuration?
e4b729f8
CB
104 nginx-upstream-configuration-name
105 nginx-upstream-configuration-servers
106
107 <nginx-location-configuration>
9c557a69
CB
108 nginx-location-configuration
109 nginx-location-configuration?
e4b729f8
CB
110 nginx-location-configuration-uri
111 nginx-location-configuration-body
112
113 <nginx-named-location-configuration>
9c557a69
CB
114 nginx-named-location-configuration
115 nginx-named-location-configuration?
e4b729f8
CB
116 nginx-named-location-configuration-name
117 nginx-named-location-configuration-body
118
24e96431 119 nginx-service
a5130d10
AW
120 nginx-service-type
121
122 fcgiwrap-configuration
123 fcgiwrap-configuration?
64bae723 124 fcgiwrap-service-type
125
126 <php-fpm-configuration>
127 php-fpm-configuration
128 make-php-fpm-configuration
129 php-fpm-configuration?
130 php-fpm-configuration-php
131 php-fpm-configuration-socket
132 php-fpm-configuration-user
133 php-fpm-configuration-group
134 php-fpm-configuration-socket-user
135 php-fpm-configuration-socket-group
136 php-fpm-configuration-pid-file
137 php-fpm-configuration-log-file
138 php-fpm-configuration-process-manager
139 php-fpm-configuration-display-errors
140 php-fpm-configuration-workers-log-file
141 php-fpm-configuration-file
142
143 <php-fpm-dynamic-process-manager-configuration>
144 php-fpm-dynamic-process-manager-configuration
145 make-php-fpm-dynamic-process-manager-configuration
146 php-fpm-dynamic-process-manager-configuration?
147 php-fpm-dynamic-process-manager-configuration-max-children
148 php-fpm-dynamic-process-manager-configuration-start-servers
149 php-fpm-dynamic-process-manager-configuration-min-spare-servers
150 php-fpm-dynamic-process-manager-configuration-max-spare-servers
151
152 <php-fpm-static-process-manager-configuration>
153 php-fpm-static-process-manager-configuration
154 make-php-fpm-static-process-manager-configuration
155 php-fpm-static-process-manager-configuration?
156 php-fpm-static-process-manager-configuration-max-children
157
158 <php-fpm-on-demand-process-manager-configuration>
159 php-fpm-on-demand-process-manager-configuration
160 make-php-fpm-on-demand-process-manager-configuration
161 php-fpm-on-demand-process-manager-configuration?
162 php-fpm-on-demand-process-manager-configuration-max-children
163 php-fpm-on-demand-process-manager-configuration-process-idle-timeout
164
165 php-fpm-service-type
08da664d
JL
166 nginx-php-location
167
93b83eb3
PAR
168 cat-avatar-generator-service
169
170 hpcguix-web-configuration
171 hpcguix-web-configuration?
19de8273
LC
172 hpcguix-web-service-type
173
174 <tailon-configuration-file>
175 tailon-configuration-file
176 tailon-configuration-file?
177 tailon-configuration-file-files
178 tailon-configuration-file-bind
179 tailon-configuration-file-relative-root
180 tailon-configuration-file-allow-transfers?
181 tailon-configuration-file-follow-names?
182 tailon-configuration-file-tail-lines
183 tailon-configuration-file-allowed-commands
184 tailon-configuration-file-debug?
185 tailon-configuration-file-http-auth
186 tailon-configuration-file-users
187
188 <tailon-configuration>
189 tailon-configuration
190 tailon-configuration?
191 tailon-configuration-config-file
192 tailon-configuration-package
193
3b97a177
MB
194 tailon-service-type
195
196 <varnish-configuration>
197 varnish-configuration
198 varnish-configuration?
199 varnish-configuration-package
200 varnish-configuration-name
201 varnish-configuration-backend
202 varnish-configuration-vcl
203 varnish-configuration-listen
204 varnish-configuration-storage
205 varnish-configuration-parameters
206 varnish-configuration-extra-options
207
208 varnish-service-type))
58724c48
DT
209
210;;; Commentary:
211;;;
212;;; Web services.
213;;;
214;;; Code:
215
d067e4ba
CB
216(define-record-type* <httpd-module>
217 httpd-module make-httpd-module
218 httpd-module?
219 (name httpd-load-module-name)
220 (file httpd-load-module-file))
221
222;; Default modules for the httpd-service-type, taken from etc/httpd/httpd.conf
223;; file in the httpd package.
224(define %default-httpd-modules
225 (map (match-lambda
226 ((name file)
227 (httpd-module
228 (name name)
229 (file file))))
230 '(("authn_file_module" "modules/mod_authn_file.so")
231 ("authn_core_module" "modules/mod_authn_core.so")
232 ("authz_host_module" "modules/mod_authz_host.so")
233 ("authz_groupfile_module" "modules/mod_authz_groupfile.so")
234 ("authz_user_module" "modules/mod_authz_user.so")
235 ("authz_core_module" "modules/mod_authz_core.so")
236 ("access_compat_module" "modules/mod_access_compat.so")
237 ("auth_basic_module" "modules/mod_auth_basic.so")
238 ("reqtimeout_module" "modules/mod_reqtimeout.so")
239 ("filter_module" "modules/mod_filter.so")
240 ("mime_module" "modules/mod_mime.so")
241 ("log_config_module" "modules/mod_log_config.so")
242 ("env_module" "modules/mod_env.so")
243 ("headers_module" "modules/mod_headers.so")
244 ("setenvif_module" "modules/mod_setenvif.so")
245 ("version_module" "modules/mod_version.so")
246 ("unixd_module" "modules/mod_unixd.so")
247 ("status_module" "modules/mod_status.so")
248 ("autoindex_module" "modules/mod_autoindex.so")
249 ("dir_module" "modules/mod_dir.so")
250 ("alias_module" "modules/mod_alias.so"))))
251
252(define-record-type* <httpd-config-file>
253 httpd-config-file make-httpd-config-file
254 httpd-config-file?
255 (modules httpd-config-file-modules
256 (default %default-httpd-modules))
257 (server-root httpd-config-file-server-root
258 (default httpd))
259 (server-name httpd-config-file-server-name
260 (default #f))
261 (document-root httpd-config-file-document-root
262 (default "/srv/http"))
263 (listen httpd-config-file-listen
264 (default '("80")))
265 (pid-file httpd-config-file-pid-file
266 (default "/var/run/httpd"))
267 (error-log httpd-config-file-error-log
268 (default "/var/log/httpd/error_log"))
269 (user httpd-config-file-user
270 (default "httpd"))
271 (group httpd-config-file-group
272 (default "httpd"))
273 (extra-config httpd-config-file-extra-config
274 (default
275 (list "TypesConfig etc/httpd/mime.types"))))
276
277(define-gexp-compiler (httpd-config-file-compiler
278 (file <httpd-config-file>) system target)
279 (match file
280 (($ <httpd-config-file> load-modules server-root server-name
281 document-root listen pid-file error-log
282 user group extra-config)
283 (gexp->derivation
284 "httpd.conf"
285 #~(call-with-output-file (ungexp output "out")
286 (lambda (port)
287 (display
288 (string-append
289 (ungexp-splicing
290 `(,@(append-map
291 (match-lambda
292 (($ <httpd-module> name module)
293 `("LoadModule " ,name " " ,module "\n")))
294 load-modules)
295 ,@`("ServerRoot " ,server-root "\n")
296 ,@(if server-name
297 `("ServerName " ,server-name "\n")
298 '())
299 ,@`("DocumentRoot " ,document-root "\n")
300 ,@(append-map
301 (lambda (listen-value)
302 `("Listen " ,listen-value "\n"))
303 listen)
304 ,@(if pid-file
305 `("Pidfile " ,pid-file "\n")
306 '())
307 ,@(if error-log
308 `("ErrorLog " ,error-log "\n")
309 '())
310 ,@(if user
311 `("User " ,user "\n")
312 '())
313 ,@(if group
314 `("Group " ,group "\n")
315 '())
316 "\n\n"
317 ,@extra-config)))
318 port)))
319 #:local-build? #t))))
320
321(define-record-type <httpd-virtualhost>
322 (httpd-virtualhost addresses-and-ports contents)
323 httpd-virtualhost?
324 (addresses-and-ports httpd-virtualhost-addresses-and-ports)
325 (contents httpd-virtualhost-contents))
326
327(define-record-type* <httpd-configuration>
328 httpd-configuration make-httpd-configuration
329 httpd-configuration?
330 (package httpd-configuration-package
331 (default httpd))
332 (pid-file httpd-configuration-pid-file
333 (default "/var/run/httpd"))
334 (config httpd-configuration-config
335 (default (httpd-config-file))))
336
337(define %httpd-accounts
338 (list (user-group (name "httpd") (system? #t))
339 (user-account
340 (name "httpd")
341 (group "httpd")
342 (system? #t)
343 (comment "Apache HTTPD server user")
344 (home-directory "/var/empty")
345 (shell (file-append shadow "/sbin/nologin")))))
346
347(define httpd-shepherd-services
348 (match-lambda
349 (($ <httpd-configuration> package pid-file config)
350 (list (shepherd-service
351 (provision '(httpd))
352 (documentation "The Apache HTTP Server")
353 (requirement '(networking))
354 (start #~(make-forkexec-constructor
355 `(#$(file-append package "/bin/httpd")
356 #$@(if config
357 (list "-f" config)
358 '()))
359 #:pid-file #$pid-file))
360 (stop #~(make-kill-destructor)))))))
361
362(define httpd-activation
363 (match-lambda
364 (($ <httpd-configuration> package pid-file config)
365 (match-record
366 config
367 <httpd-config-file>
368 (error-log document-root)
369 #~(begin
370 (use-modules (guix build utils))
371
372 (mkdir-p #$(dirname error-log))
373 (mkdir-p #$document-root))))))
374
375(define (httpd-process-extensions original-config extension-configs)
376 (let ((config (httpd-configuration-config
377 original-config)))
378 (if (httpd-config-file? config)
379 (httpd-configuration
380 (inherit original-config)
381 (config
382 (httpd-config-file
383 (inherit config)
384 (extra-config
385 (append (httpd-config-file-extra-config config)
386 (append-map
387 (match-lambda
388 (($ <httpd-virtualhost>
389 addresses-and-ports
390 contents)
391 `(,(string-append
392 "<VirtualHost " addresses-and-ports ">\n")
393 ,@contents
394 "\n</VirtualHost>\n"))
395 ((? string? x)
396 `("\n" ,x "\n"))
397 ((? list? x)
398 `("\n" ,@x "\n")))
399 extension-configs)))))))))
400
401(define httpd-service-type
402 (service-type (name 'httpd)
403 (extensions
404 (list (service-extension shepherd-root-service-type
405 httpd-shepherd-services)
406 (service-extension activation-service-type
407 httpd-activation)
408 (service-extension account-service-type
409 (const %httpd-accounts))))
410 (compose concatenate)
411 (extend httpd-process-extensions)
412 (default-value
413 (httpd-configuration))))
414
3b9b12ef
JL
415(define-record-type* <nginx-server-configuration>
416 nginx-server-configuration make-nginx-server-configuration
417 nginx-server-configuration?
8b223cea
CL
418 (listen nginx-server-configuration-listen
419 (default '("80" "443 ssl")))
3b9b12ef 420 (server-name nginx-server-configuration-server-name
8c00b838 421 (default (list 'default)))
3b9b12ef 422 (root nginx-server-configuration-root
8c00b838 423 (default "/srv/http"))
9c557a69
CB
424 (locations nginx-server-configuration-locations
425 (default '()))
3b9b12ef 426 (index nginx-server-configuration-index
8c00b838 427 (default (list "index.html")))
4d14808a
OP
428 (try-files nginx-server-configuration-try-files
429 (default '()))
3b9b12ef 430 (ssl-certificate nginx-server-configuration-ssl-certificate
c48aa70a 431 (default #f))
3b9b12ef 432 (ssl-certificate-key nginx-server-configuration-ssl-certificate-key
c48aa70a 433 (default #f))
3b9b12ef 434 (server-tokens? nginx-server-configuration-server-tokens?
b05e8ee1
CL
435 (default #f))
436 (raw-content nginx-server-configuration-raw-content
437 (default '())))
8c00b838 438
cb341293
CB
439(define-record-type* <nginx-upstream-configuration>
440 nginx-upstream-configuration make-nginx-upstream-configuration
441 nginx-upstream-configuration?
442 (name nginx-upstream-configuration-name)
443 (servers nginx-upstream-configuration-servers))
444
9c557a69
CB
445(define-record-type* <nginx-location-configuration>
446 nginx-location-configuration make-nginx-location-configuration
447 nginx-location-configuration?
448 (uri nginx-location-configuration-uri
449 (default #f))
450 (body nginx-location-configuration-body))
451
452(define-record-type* <nginx-named-location-configuration>
453 nginx-named-location-configuration make-nginx-named-location-configuration
454 nginx-named-location-configuration?
455 (name nginx-named-location-configuration-name
456 (default #f))
457 (body nginx-named-location-configuration-body))
458
0adfe95a
LC
459(define-record-type* <nginx-configuration>
460 nginx-configuration make-nginx-configuration
461 nginx-configuration?
dc72a7f7
LC
462 (nginx nginx-configuration-nginx ;<package>
463 (default nginx))
464 (log-directory nginx-configuration-log-directory ;string
465 (default "/var/log/nginx"))
466 (run-directory nginx-configuration-run-directory ;string
467 (default "/var/run/nginx"))
468 (server-blocks nginx-configuration-server-blocks
469 (default '())) ;list of <nginx-server-configuration>
470 (upstream-blocks nginx-configuration-upstream-blocks
471 (default '())) ;list of <nginx-upstream-configuration>
2881f852
CB
472 (server-names-hash-bucket-size nginx-configuration-server-names-hash-bucket-size
473 (default #f))
474 (server-names-hash-bucket-max-size nginx-configuration-server-names-hash-bucket-max-size
475 (default #f))
25e071ea
CB
476 (extra-content nginx-configuration-extra-content
477 (default ""))
dc72a7f7
LC
478 (file nginx-configuration-file ;#f | string | file-like
479 (default #f)))
0adfe95a 480
8c00b838
JL
481(define (config-domain-strings names)
482 "Return a string denoting the nginx config representation of NAMES, a list
483of domain names."
c9aa261b 484 (map (match-lambda
4e9ae301 485 ('default "_ ")
c9aa261b
AW
486 ((? string? str) (list str " ")))
487 names))
8c00b838
JL
488
489(define (config-index-strings names)
490 "Return a string denoting the nginx config representation of NAMES, a list
491of index files."
c9aa261b
AW
492 (map (match-lambda
493 ((? string? str) (list str " ")))
494 names))
8c00b838 495
c9aa261b 496(define emit-nginx-location-config
9c557a69
CB
497 (match-lambda
498 (($ <nginx-location-configuration> uri body)
c9aa261b 499 (list
9c557a69 500 " location " uri " {\n"
c9aa261b 501 (map (lambda (x) (list " " x "\n")) body)
9c557a69
CB
502 " }\n"))
503 (($ <nginx-named-location-configuration> name body)
c9aa261b 504 (list
9c557a69 505 " location @" name " {\n"
c9aa261b 506 (map (lambda (x) (list " " x "\n")) body)
9c557a69
CB
507 " }\n"))))
508
c9aa261b 509(define (emit-nginx-server-config server)
8b223cea 510 (let ((listen (nginx-server-configuration-listen server))
c9aa261b
AW
511 (server-name (nginx-server-configuration-server-name server))
512 (ssl-certificate (nginx-server-configuration-ssl-certificate server))
513 (ssl-certificate-key
514 (nginx-server-configuration-ssl-certificate-key server))
515 (root (nginx-server-configuration-root server))
516 (index (nginx-server-configuration-index server))
4d14808a 517 (try-files (nginx-server-configuration-try-files server))
c9aa261b 518 (server-tokens? (nginx-server-configuration-server-tokens? server))
b05e8ee1
CL
519 (locations (nginx-server-configuration-locations server))
520 (raw-content (nginx-server-configuration-raw-content server)))
c9aa261b
AW
521 (define-syntax-parameter <> (syntax-rules ()))
522 (define-syntax-rule (and/l x tail ...)
523 (let ((x* x))
524 (if x*
525 (syntax-parameterize ((<> (identifier-syntax x*)))
526 (list tail ...))
527 '())))
528 (list
529 " server {\n"
8b223cea 530 (map (lambda (directive) (list " listen " directive ";\n")) listen)
c9aa261b
AW
531 " server_name " (config-domain-strings server-name) ";\n"
532 (and/l ssl-certificate " ssl_certificate " <> ";\n")
533 (and/l ssl-certificate-key " ssl_certificate_key " <> ";\n")
534 " root " root ";\n"
535 " index " (config-index-strings index) ";\n"
4d14808a
OP
536 (if (not (nil? try-files))
537 (and/l (config-index-strings try-files) " try_files " <> ";\n")
538 "")
c9aa261b
AW
539 " server_tokens " (if server-tokens? "on" "off") ";\n"
540 "\n"
541 (map emit-nginx-location-config locations)
542 "\n"
b05e8ee1 543 (map (lambda (x) (list " " x "\n")) raw-content)
c9aa261b 544 " }\n")))
cb341293 545
c9aa261b
AW
546(define (emit-nginx-upstream-config upstream)
547 (list
cb341293 548 " upstream " (nginx-upstream-configuration-name upstream) " {\n"
c9aa261b
AW
549 (map (lambda (server)
550 (simple-format #f " server ~A;\n" server))
551 (nginx-upstream-configuration-servers upstream))
8c00b838
JL
552 " }\n"))
553
c9aa261b
AW
554(define (flatten . lst)
555 "Return a list that recursively concatenates all sub-lists of LST."
556 (define (flatten1 head out)
557 (if (list? head)
558 (fold-right flatten1 out head)
559 (cons head out)))
560 (fold-right flatten1 '() lst))
561
472368a8
CB
562(define (default-nginx-config config)
563 (match-record config
564 <nginx-configuration>
565 (nginx log-directory run-directory
566 server-blocks upstream-blocks
567 server-names-hash-bucket-size
25e071ea
CB
568 server-names-hash-bucket-max-size
569 extra-content)
472368a8
CB
570 (apply mixed-text-file "nginx.conf"
571 (flatten
572 "user nginx nginx;\n"
573 "pid " run-directory "/pid;\n"
574 "error_log " log-directory "/error.log info;\n"
575 "http {\n"
576 " client_body_temp_path " run-directory "/client_body_temp;\n"
577 " proxy_temp_path " run-directory "/proxy_temp;\n"
578 " fastcgi_temp_path " run-directory "/fastcgi_temp;\n"
579 " uwsgi_temp_path " run-directory "/uwsgi_temp;\n"
580 " scgi_temp_path " run-directory "/scgi_temp;\n"
581 " access_log " log-directory "/access.log;\n"
582 " include " nginx "/share/nginx/conf/mime.types;\n"
583 (if server-names-hash-bucket-size
584 (string-append
585 " server_names_hash_bucket_size "
586 (number->string server-names-hash-bucket-size)
587 ";\n")
588 "")
589 (if server-names-hash-bucket-max-size
590 (string-append
591 " server_names_hash_bucket_max_size "
592 (number->string server-names-hash-bucket-max-size)
593 ";\n")
594 "")
595 "\n"
596 (map emit-nginx-upstream-config upstream-blocks)
597 (map emit-nginx-server-config server-blocks)
25e071ea
CB
598 extra-content
599 "\n}\n"
472368a8 600 "events {}\n"))))
58724c48 601
0adfe95a
LC
602(define %nginx-accounts
603 (list (user-group (name "nginx") (system? #t))
604 (user-account
605 (name "nginx")
606 (group "nginx")
607 (system? #t)
608 (comment "nginx server user")
609 (home-directory "/var/empty")
9e41130b 610 (shell (file-append shadow "/sbin/nologin")))))
0adfe95a 611
472368a8
CB
612(define (nginx-activation config)
613 (match-record config
614 <nginx-configuration>
615 (nginx log-directory run-directory file)
616 #~(begin
617 (use-modules (guix build utils))
0adfe95a 618
472368a8
CB
619 (format #t "creating nginx log directory '~a'~%" #$log-directory)
620 (mkdir-p #$log-directory)
621 (format #t "creating nginx run directory '~a'~%" #$run-directory)
622 (mkdir-p #$run-directory)
623 (format #t "creating nginx temp directories '~a/{client_body,proxy,fastcgi,uwsgi,scgi}_temp'~%" #$run-directory)
624 (mkdir-p (string-append #$run-directory "/client_body_temp"))
625 (mkdir-p (string-append #$run-directory "/proxy_temp"))
626 (mkdir-p (string-append #$run-directory "/fastcgi_temp"))
627 (mkdir-p (string-append #$run-directory "/uwsgi_temp"))
628 (mkdir-p (string-append #$run-directory "/scgi_temp"))
629 ;; Start-up logs. Once configuration is loaded, nginx switches to
630 ;; log-directory.
631 (mkdir-p (string-append #$run-directory "/logs"))
632 ;; Check configuration file syntax.
633 (system* (string-append #$nginx "/sbin/nginx")
634 "-c" #$(or file
635 (default-nginx-config config))
636 "-t"))))
0adfe95a 637
472368a8
CB
638(define (nginx-shepherd-service config)
639 (match-record config
640 <nginx-configuration>
641 (nginx file run-directory)
642 (let* ((nginx-binary (file-append nginx "/sbin/nginx"))
9fc29227 643 (pid-file (in-vicinity run-directory "pid"))
472368a8
CB
644 (nginx-action
645 (lambda args
646 #~(lambda _
4ae0607d
CL
647 (invoke #$nginx-binary "-c"
648 #$(or file
649 (default-nginx-config config))
9fc29227
CL
650 #$@args)
651 (match '#$args
e80c725d 652 (("-s" . _) #f)
9fc29227 653 (_
985975ae
LC
654 ;; When FILE is true, we cannot be sure that PID-FILE will
655 ;; be created, so assume it won't show up. When FILE is
656 ;; false, read PID-FILE.
657 #$(if file
658 #~#t
659 #~(read-pid-file #$pid-file))))))))
0adfe95a 660
472368a8
CB
661 ;; TODO: Add 'reload' action.
662 (list (shepherd-service
663 (provision '(nginx))
664 (documentation "Run the nginx daemon.")
665 (requirement '(user-processes loopback))
9fc29227
CL
666 (modules `((ice-9 match)
667 ,@%default-modules))
472368a8
CB
668 (start (nginx-action "-p" run-directory))
669 (stop (nginx-action "-s" "stop")))))))
0adfe95a
LC
670
671(define nginx-service-type
672 (service-type (name 'nginx)
673 (extensions
d4053c71
AK
674 (list (service-extension shepherd-root-service-type
675 nginx-shepherd-service)
0adfe95a
LC
676 (service-extension activation-service-type
677 nginx-activation)
678 (service-extension account-service-type
d338237d
JL
679 (const %nginx-accounts))))
680 (compose concatenate)
681 (extend (lambda (config servers)
682 (nginx-configuration
683 (inherit config)
684 (server-blocks
685 (append (nginx-configuration-server-blocks config)
ad4cc435
CB
686 servers)))))
687 (default-value
688 (nginx-configuration))))
0adfe95a 689
a5130d10
AW
690(define-record-type* <fcgiwrap-configuration> fcgiwrap-configuration
691 make-fcgiwrap-configuration
692 fcgiwrap-configuration?
693 (package fcgiwrap-configuration-package ;<package>
694 (default fcgiwrap))
695 (socket fcgiwrap-configuration-socket
696 (default "tcp:127.0.0.1:9000"))
697 (user fcgiwrap-configuration-user
698 (default "fcgiwrap"))
699 (group fcgiwrap-configuration-group
700 (default "fcgiwrap")))
701
702(define fcgiwrap-accounts
703 (match-lambda
704 (($ <fcgiwrap-configuration> package socket user group)
705 (filter identity
706 (list
707 (and (equal? group "fcgiwrap")
708 (user-group
709 (name "fcgiwrap")
710 (system? #t)))
711 (and (equal? user "fcgiwrap")
712 (user-account
713 (name "fcgiwrap")
714 (group group)
715 (system? #t)
716 (comment "Fcgiwrap Daemon")
717 (home-directory "/var/empty")
718 (shell (file-append shadow "/sbin/nologin")))))))))
719
720(define fcgiwrap-shepherd-service
721 (match-lambda
722 (($ <fcgiwrap-configuration> package socket user group)
723 (list (shepherd-service
724 (provision '(fcgiwrap))
725 (documentation "Run the fcgiwrap daemon.")
726 (requirement '(networking))
727 (start #~(make-forkexec-constructor
728 '(#$(file-append package "/sbin/fcgiwrap")
729 "-s" #$socket)
730 #:user #$user #:group #$group))
731 (stop #~(make-kill-destructor)))))))
732
733(define fcgiwrap-service-type
734 (service-type (name 'fcgiwrap)
735 (extensions
736 (list (service-extension shepherd-root-service-type
737 fcgiwrap-shepherd-service)
738 (service-extension account-service-type
739 fcgiwrap-accounts)))
740 (default-value (fcgiwrap-configuration))))
64bae723 741
742(define-record-type* <php-fpm-configuration> php-fpm-configuration
743 make-php-fpm-configuration
744 php-fpm-configuration?
745 (php php-fpm-configuration-php ;<package>
746 (default php))
747 (socket php-fpm-configuration-socket
748 (default (string-append "/var/run/php"
749 (version-major (package-version php))
750 "-fpm.sock")))
751 (user php-fpm-configuration-user
752 (default "php-fpm"))
753 (group php-fpm-configuration-group
754 (default "php-fpm"))
755 (socket-user php-fpm-configuration-socket-user
756 (default "php-fpm"))
757 (socket-group php-fpm-configuration-socket-group
758 (default "nginx"))
759 (pid-file php-fpm-configuration-pid-file
760 (default (string-append "/var/run/php"
761 (version-major (package-version php))
762 "-fpm.pid")))
763 (log-file php-fpm-configuration-log-file
764 (default (string-append "/var/log/php"
765 (version-major (package-version php))
766 "-fpm.log")))
767 (process-manager php-fpm-configuration-process-manager
768 (default (php-fpm-dynamic-process-manager-configuration)))
769 (display-errors php-fpm-configuration-display-errors
770 (default #f))
771 (workers-log-file php-fpm-configuration-workers-log-file
772 (default (string-append "/var/log/php"
773 (version-major (package-version php))
774 "-fpm.www.log")))
775 (file php-fpm-configuration-file ;#f | file-like
776 (default #f)))
777
778(define-record-type* <php-fpm-dynamic-process-manager-configuration>
779 php-fpm-dynamic-process-manager-configuration
780 make-php-fpm-dynamic-process-manager-configuration
781 php-fpm-dynamic-process-manager-configuration?
782 (max-children php-fpm-dynamic-process-manager-configuration-max-children
783 (default 5))
784 (start-servers php-fpm-dynamic-process-manager-configuration-start-servers
785 (default 2))
786 (min-spare-servers php-fpm-dynamic-process-manager-configuration-min-spare-servers
787 (default 1))
788 (max-spare-servers php-fpm-dynamic-process-manager-configuration-max-spare-servers
789 (default 3)))
790
791(define-record-type* <php-fpm-static-process-manager-configuration>
792 php-fpm-static-process-manager-configuration
793 make-php-fpm-static-process-manager-configuration
794 php-fpm-static-process-manager-configuration?
795 (max-children php-fpm-static-process-manager-configuration-max-children
796 (default 5)))
797
798(define-record-type* <php-fpm-on-demand-process-manager-configuration>
799 php-fpm-on-demand-process-manager-configuration
800 make-php-fpm-on-demand-process-manager-configuration
801 php-fpm-on-demand-process-manager-configuration?
802 (max-children php-fpm-on-demand-process-manager-configuration-max-children
803 (default 5))
804 (process-idle-timeout php-fpm-on-demand-process-manager-configuration-process-idle-timeout
805 (default 10)))
806
807(define php-fpm-accounts
808 (match-lambda
809 (($ <php-fpm-configuration> php socket user group socket-user socket-group _ _ _ _ _ _)
810 (list
811 (user-group (name "php-fpm") (system? #t))
812 (user-group
813 (name group)
814 (system? #t))
815 (user-account
816 (name user)
817 (group group)
818 (supplementary-groups '("php-fpm"))
819 (system? #t)
820 (comment "php-fpm daemon user")
821 (home-directory "/var/empty")
822 (shell (file-append shadow "/sbin/nologin")))))))
823
824(define (default-php-fpm-config socket user group socket-user socket-group
825 pid-file log-file pm display-errors workers-log-file)
826 (apply mixed-text-file "php-fpm.conf"
827 (flatten
828 "[global]\n"
829 "pid =" pid-file "\n"
830 "error_log =" log-file "\n"
831 "[www]\n"
832 "user =" user "\n"
833 "group =" group "\n"
834 "listen =" socket "\n"
835 "listen.owner =" socket-user "\n"
836 "listen.group =" socket-group "\n"
837
838 (match pm
839 (($ <php-fpm-dynamic-process-manager-configuration>
840 pm.max-children
841 pm.start-servers
842 pm.min-spare-servers
843 pm.max-spare-servers)
844 (list
845 "pm = dynamic\n"
846 "pm.max_children =" (number->string pm.max-children) "\n"
847 "pm.start_servers =" (number->string pm.start-servers) "\n"
848 "pm.min_spare_servers =" (number->string pm.min-spare-servers) "\n"
849 "pm.max_spare_servers =" (number->string pm.max-spare-servers) "\n"))
850
851 (($ <php-fpm-static-process-manager-configuration>
852 pm.max-children)
853 (list
854 "pm = static\n"
855 "pm.max_children =" (number->string pm.max-children) "\n"))
856
857 (($ <php-fpm-on-demand-process-manager-configuration>
858 pm.max-children
859 pm.process-idle-timeout)
860 (list
861 "pm = ondemand\n"
862 "pm.max_children =" (number->string pm.max-children) "\n"
863 "pm.process_idle_timeout =" (number->string pm.process-idle-timeout) "s\n")))
864
865
866 "php_flag[display_errors] = " (if display-errors "on" "off") "\n"
867
868 (if workers-log-file
869 (list "catch_workers_output = yes\n"
870 "php_admin_value[error_log] =" workers-log-file "\n"
871 "php_admin_flag[log_errors] = on\n")
872 (list "catch_workers_output = no\n")))))
873
874(define php-fpm-shepherd-service
875 (match-lambda
876 (($ <php-fpm-configuration> php socket user group socket-user socket-group
877 pid-file log-file pm display-errors workers-log-file file)
878 (list (shepherd-service
879 (provision '(php-fpm))
880 (documentation "Run the php-fpm daemon.")
881 (requirement '(networking))
882 (start #~(make-forkexec-constructor
883 '(#$(file-append php "/sbin/php-fpm")
884 "--fpm-config"
885 #$(or file
886 (default-php-fpm-config socket user group
887 socket-user socket-group pid-file log-file
888 pm display-errors workers-log-file)))
889 #:pid-file #$pid-file))
890 (stop #~(make-kill-destructor)))))))
891
892(define php-fpm-activation
893 (match-lambda
894 (($ <php-fpm-configuration> _ _ user _ _ _ _ log-file _ _ workers-log-file _)
895 #~(begin
896 (use-modules (guix build utils))
897 (let* ((user (getpwnam #$user))
898 (touch (lambda (file-name)
899 (call-with-output-file file-name (const #t))))
900 (init-log-file
901 (lambda (file-name)
902 (when #$workers-log-file
903 (when (not (file-exists? file-name))
904 (touch file-name))
905 (chown file-name (passwd:uid user) (passwd:gid user))
906 (chmod file-name #o660)))))
907 (init-log-file #$log-file)
908 (init-log-file #$workers-log-file))))))
909
910
911(define php-fpm-service-type
912 (service-type
913 (name 'php-fpm)
914 (description
915 "Run @command{php-fpm} to provide a fastcgi socket for calling php through
916a webserver.")
917 (extensions
918 (list (service-extension shepherd-root-service-type
919 php-fpm-shepherd-service)
920 (service-extension activation-service-type
921 php-fpm-activation)
922 (service-extension account-service-type
923 php-fpm-accounts)))
924 (default-value (php-fpm-configuration))))
925
926(define* (nginx-php-location
927 #:key
928 (nginx-package nginx)
929 (socket (string-append "/var/run/php"
930 (version-major (package-version php))
931 "-fpm.sock")))
932 "Return a nginx-location-configuration that makes nginx run .php files."
933 (nginx-location-configuration
934 (uri "~ \\.php$")
935 (body (list
936 "fastcgi_split_path_info ^(.+\\.php)(/.+)$;"
937 (string-append "fastcgi_pass unix:" socket ";")
938 "fastcgi_index index.php;"
939 (list "include " nginx-package "/share/nginx/conf/fastcgi.conf;")))))
08da664d
JL
940
941(define* (cat-avatar-generator-service
942 #:key
943 (cache-dir "/var/cache/cat-avatar-generator")
944 (package cat-avatar-generator)
945 (configuration (nginx-server-configuration)))
946 (simple-service
947 'cat-http-server nginx-service-type
948 (list (nginx-server-configuration
949 (inherit configuration)
950 (locations
951 (cons
952 (let ((base (nginx-php-location)))
953 (nginx-location-configuration
954 (inherit base)
955 (body (list (string-append "fastcgi_param CACHE_DIR \""
956 cache-dir "\";")
957 (nginx-location-configuration-body base)))))
958 (nginx-server-configuration-locations configuration)))
959 (root #~(string-append #$package
960 "/share/web/cat-avatar-generator"))))))
93b83eb3
PAR
961
962\f
963(define-record-type* <hpcguix-web-configuration>
964 hpcguix-web-configuration make-hpcguix-web-configuration
965 hpcguix-web-configuration?
966
967 (package hpcguix-web-package (default hpcguix-web)) ;<package>
968
969 ;; Specs is gexp of hpcguix-web configuration file
970 (specs hpcguix-web-configuration-specs))
971
972(define %hpcguix-web-accounts
973 (list (user-group
974 (name "hpcguix-web")
975 (system? #t))
976 (user-account
977 (name "hpcguix-web")
978 (group "hpcguix-web")
979 (system? #t)
980 (comment "hpcguix-web")
981 (home-directory "/var/empty")
982 (shell (file-append shadow "/sbin/nologin")))))
983
984(define %hpcguix-web-activation
985 #~(begin
986 (use-modules (guix build utils))
987 (let ((home-dir "/var/cache/guix/web")
988 (user (getpwnam "hpcguix-web")))
989 (mkdir-p home-dir)
990 (chown home-dir (passwd:uid user) (passwd:gid user))
991 (chmod home-dir #o755))))
992
81317071
LC
993(define %hpcguix-web-log-file
994 "/var/log/hpcguix-web.log")
995
996(define %hpcguix-web-log-rotations
997 (list (log-rotation
998 (files (list %hpcguix-web-log-file))
999 (frequency 'weekly))))
1000
93b83eb3
PAR
1001(define (hpcguix-web-shepherd-service config)
1002 (let ((specs (hpcguix-web-configuration-specs config))
1003 (hpcguix-web (hpcguix-web-package config)))
1004 (with-imported-modules (source-module-closure
1005 '((gnu build shepherd)))
1006 (shepherd-service
1007 (documentation "hpcguix-web daemon")
1008 (provision '(hpcguix-web))
1009 (requirement '(networking))
1010 (start #~(make-forkexec-constructor
1011 (list #$(file-append hpcguix-web "/bin/run")
1012 (string-append "--config="
1013 #$(scheme-file "hpcguix-web.scm" specs)))
1014 #:user "hpcguix-web"
1015 #:group "hpcguix-web"
1016 #:environment-variables
7df94565 1017 (list "XDG_CACHE_HOME=/var/cache"
81317071
LC
1018 "SSL_CERT_DIR=/etc/ssl/certs")
1019 #:log-file #$%hpcguix-web-log-file))
93b83eb3
PAR
1020 (stop #~(make-kill-destructor))))))
1021
1022(define hpcguix-web-service-type
1023 (service-type
1024 (name 'hpcguix-web)
1025 (description "Run the hpcguix-web server.")
1026 (extensions
1027 (list (service-extension account-service-type
1028 (const %hpcguix-web-accounts))
1029 (service-extension activation-service-type
1030 (const %hpcguix-web-activation))
81317071
LC
1031 (service-extension rottlog-service-type
1032 (const %hpcguix-web-log-rotations))
93b83eb3
PAR
1033 (service-extension shepherd-root-service-type
1034 (compose list hpcguix-web-shepherd-service))))))
19de8273
LC
1035
1036\f
1037;;;
1038;;; Tailon
1039;;;
1040
1041(define-record-type* <tailon-configuration-file>
1042 tailon-configuration-file make-tailon-configuration-file
1043 tailon-configuration-file?
1044 (files tailon-configuration-file-files
1045 (default '("/var/log")))
1046 (bind tailon-configuration-file-bind
1047 (default "localhost:8080"))
1048 (relative-root tailon-configuration-file-relative-root
1049 (default #f))
1050 (allow-transfers? tailon-configuration-file-allow-transfers?
1051 (default #t))
1052 (follow-names? tailon-configuration-file-follow-names?
1053 (default #t))
1054 (tail-lines tailon-configuration-file-tail-lines
1055 (default 200))
1056 (allowed-commands tailon-configuration-file-allowed-commands
1057 (default '("tail" "grep" "awk")))
1058 (debug? tailon-configuration-file-debug?
1059 (default #f))
1060 (wrap-lines tailon-configuration-file-wrap-lines
1061 (default #t))
1062 (http-auth tailon-configuration-file-http-auth
1063 (default #f))
1064 (users tailon-configuration-file-users
1065 (default #f)))
1066
1067(define (tailon-configuration-files-string files)
1068 (string-append
1069 "\n"
1070 (string-join
1071 (map
1072 (lambda (x)
1073 (string-append
1074 " - "
1075 (cond
1076 ((string? x)
1077 (simple-format #f "'~A'" x))
1078 ((list? x)
1079 (string-join
1080 (cons (simple-format #f "'~A':" (car x))
1081 (map
1082 (lambda (x) (simple-format #f " - '~A'" x))
1083 (cdr x)))
1084 "\n"))
1085 (else (error x)))))
1086 files)
1087 "\n")))
1088
1089(define-gexp-compiler (tailon-configuration-file-compiler
1090 (file <tailon-configuration-file>) system target)
1091 (match file
1092 (($ <tailon-configuration-file> files bind relative-root
1093 allow-transfers? follow-names?
1094 tail-lines allowed-commands debug?
1095 wrap-lines http-auth users)
1096 (text-file
1097 "tailon-config.yaml"
1098 (string-concatenate
1099 (filter-map
1100 (match-lambda
1101 ((key . #f) #f)
1102 ((key . value) (string-append key ": " value "\n")))
1103
1104 `(("files" . ,(tailon-configuration-files-string files))
1105 ("bind" . ,bind)
1106 ("relative-root" . ,relative-root)
1107 ("allow-transfers" . ,(if allow-transfers? "true" "false"))
1108 ("follow-names" . ,(if follow-names? "true" "false"))
1109 ("tail-lines" . ,(number->string tail-lines))
1110 ("commands" . ,(string-append "["
1111 (string-join allowed-commands ", ")
1112 "]"))
1113 ("debug" . ,(if debug? "true" #f))
1114 ("wrap-lines" . ,(if wrap-lines "true" "false"))
1115 ("http-auth" . ,http-auth)
1116 ("users" . ,(if users
1117 (string-concatenate
1118 (cons "\n"
1119 (map (match-lambda
1120 ((user . pass)
1121 (string-append
1122 " " user ":" pass)))
1123 users)))
1124 #f)))))))))
1125
1126(define-record-type* <tailon-configuration>
1127 tailon-configuration make-tailon-configuration
1128 tailon-configuration?
1129 (config-file tailon-configuration-config-file
1130 (default (tailon-configuration-file)))
1131 (package tailon-configuration-package
1132 (default tailon)))
1133
1134(define tailon-shepherd-service
1135 (match-lambda
1136 (($ <tailon-configuration> config-file package)
1137 (list (shepherd-service
1138 (provision '(tailon))
1139 (documentation "Run the tailon daemon.")
1140 (start #~(make-forkexec-constructor
1141 `(,(string-append #$package "/bin/tailon")
1142 "-c" ,#$config-file)
1143 #:user "tailon"
1144 #:group "tailon"))
1145 (stop #~(make-kill-destructor)))))))
1146
1147(define %tailon-accounts
1148 (list (user-group (name "tailon") (system? #t))
1149 (user-account
1150 (name "tailon")
1151 (group "tailon")
1152 (system? #t)
1153 (comment "tailon")
1154 (home-directory "/var/empty")
1155 (shell (file-append shadow "/sbin/nologin")))))
1156
1157(define tailon-service-type
1158 (service-type
1159 (name 'tailon)
1160 (description
1161 "Run Tailon, a Web application for monitoring, viewing, and searching log
1162files.")
1163 (extensions
1164 (list (service-extension shepherd-root-service-type
1165 tailon-shepherd-service)
1166 (service-extension account-service-type
1167 (const %tailon-accounts))))
1168 (compose concatenate)
1169 (extend (lambda (parameter files)
1170 (tailon-configuration
1171 (inherit parameter)
1172 (config-file
1173 (let ((old-config-file
1174 (tailon-configuration-config-file parameter)))
1175 (tailon-configuration-file
1176 (inherit old-config-file)
1177 (files (append (tailon-configuration-file-files old-config-file)
1178 files))))))))
1179 (default-value (tailon-configuration))))
3b97a177
MB
1180
1181\f
1182;;;
1183;;; Varnish
1184;;;
1185
1186(define-record-type* <varnish-configuration>
1187 varnish-configuration make-varnish-configuration
1188 varnish-configuration?
1189 (package varnish-configuration-package ;<package>
1190 (default varnish))
1191 (name varnish-configuration-name ;string
1192 (default "default"))
1193 (backend varnish-configuration-backend ;string
1194 (default "localhost:8080"))
1195 (vcl varnish-configuration-vcl ;#f | <file-like>
1196 (default #f))
1197 (listen varnish-configuration-listen ;list of strings
1198 (default '("localhost:80")))
1199 (storage varnish-configuration-storage ;list of strings
1200 (default '("malloc,128m")))
1201 (parameters varnish-configuration-parameters ;list of string pairs
1202 (default '()))
1203 (extra-options varnish-configuration-extra-options ;list of strings
1204 (default '())))
1205
1206(define %varnish-accounts
1207 (list (user-group
1208 (name "varnish")
1209 (system? #t))
1210 (user-account
1211 (name "varnish")
1212 (group "varnish")
1213 (system? #t)
1214 (comment "Varnish Cache User")
1215 (home-directory "/var/varnish")
1216 (shell (file-append shadow "/sbin/nologin")))))
1217
1218(define varnish-shepherd-service
1219 (match-lambda
1220 (($ <varnish-configuration> package name backend vcl listen storage
1221 parameters extra-options)
1222 (list (shepherd-service
1223 (provision (list (symbol-append 'varnish- (string->symbol name))))
1224 (documentation (string-append "The Varnish Web Accelerator"
1225 " (" name ")"))
1226 (requirement '(networking))
1227 (start #~(make-forkexec-constructor
1228 (list #$(file-append package "/sbin/varnishd")
1229 "-n" #$name
1230 #$@(if vcl
1231 #~("-f" #$vcl)
1232 #~("-b" #$backend))
1233 #$@(append-map (lambda (a) (list "-a" a)) listen)
1234 #$@(append-map (lambda (s) (list "-s" s)) storage)
1235 #$@(append-map (lambda (p)
1236 (list "-p" (format #f "~a=~a"
1237 (car p) (cdr p))))
1238 parameters)
1239 #$@extra-options)
1240 ;; Varnish will drop privileges to the "varnish" user when
1241 ;; it exists. Not passing #:user here allows the service
1242 ;; to bind to ports < 1024.
1243 #:pid-file (if (string-prefix? "/" #$name)
1244 (string-append #$name "/_.pid")
1245 (string-append "/var/varnish/" #$name "/_.pid"))))
1246 (stop #~(make-kill-destructor)))))))
1247
1248(define varnish-service-type
1249 (service-type
1250 (name 'varnish)
1251 (description "Run the Varnish cache server.")
1252 (extensions
1253 (list (service-extension account-service-type
1254 (const %varnish-accounts))
1255 (service-extension shepherd-root-service-type
1256 varnish-shepherd-service)))
1257 (default-value
1258 (varnish-configuration))))