gnu: Add cat-avatar-generator.
[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>
0f4740f4 5;;; Copyright © 2016, 2017 Julien Lepiller <julien@lepiller.eu>
cb341293 6;;; Copyright © 2017 Christopher Baines <mail@cbaines.net>
64bae723 7;;; Copyright © 2017 nee <nee-git@hidamari.blue>
8b223cea 8;;; Copyright © 2017 Clément Lassieur <clement@lassieur.org>
58724c48
DT
9;;;
10;;; This file is part of GNU Guix.
11;;;
12;;; GNU Guix is free software; you can redistribute it and/or modify it
13;;; under the terms of the GNU General Public License as published by
14;;; the Free Software Foundation; either version 3 of the License, or (at
15;;; your option) any later version.
16;;;
17;;; GNU Guix is distributed in the hope that it will be useful, but
18;;; WITHOUT ANY WARRANTY; without even the implied warranty of
19;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;;; GNU General Public License for more details.
21;;;
22;;; You should have received a copy of the GNU General Public License
23;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
24
25(define-module (gnu services web)
26 #:use-module (gnu services)
0190c1c0 27 #:use-module (gnu services shepherd)
58724c48
DT
28 #:use-module (gnu system shadow)
29 #:use-module (gnu packages admin)
30 #:use-module (gnu packages web)
64bae723 31 #:use-module (gnu packages php)
58724c48 32 #:use-module (guix records)
58724c48 33 #:use-module (guix gexp)
64bae723 34 #:use-module ((guix utils) #:select (version-major))
35 #:use-module ((guix packages) #:select (package-version))
d338237d 36 #:use-module (srfi srfi-1)
d067e4ba 37 #:use-module (srfi srfi-9)
0adfe95a 38 #:use-module (ice-9 match)
d067e4ba
CB
39 #:export (<httpd-configuration>
40 httpd-configuration
41 httpd-configuration?
42 httpd-configuration-package
43 httpd-configuration-pid-file
44 httpd-configuration-config
45
46 <httpd-virtualhost>
47 httpd-virtualhost
48 httpd-virtualhost?
49 httpd-virtualhost-addresses-and-ports
50 httpd-virtualhost-contents
51
52 <httpd-config-file>
53 httpd-config-file
54 httpd-config-file?
55 httpd-config-file-modules
56 httpd-config-file-server-root
57 httpd-config-file-server-name
58 httpd-config-file-listen
59 httpd-config-file-pid-file
60 httpd-config-file-error-log
61 httpd-config-file-user
62 httpd-config-file-group
63
64 httpd-service-type
65
66 <nginx-configuration>
e4b729f8 67 nginx-configuration
24e96431 68 nginx-configuration?
e4b729f8
CB
69 nginx-configuartion-nginx
70 nginx-configuration-log-directory
71 nginx-configuration-run-directory
72 nginx-configuration-server-blocks
73 nginx-configuration-upstream-blocks
2881f852
CB
74 nginx-configuration-server-names-hash-bucket-size
75 nginx-configuration-server-names-hash-bucket-max-size
e4b729f8
CB
76 nginx-configuration-file
77
78 <nginx-server-configuration>
3b9b12ef
JL
79 nginx-server-configuration
80 nginx-server-configuration?
8b223cea 81 nginx-server-configuration-listen
e4b729f8
CB
82 nginx-server-configuration-server-name
83 nginx-server-configuration-root
84 nginx-server-configuration-locations
85 nginx-server-configuration-index
86 nginx-server-configuration-ssl-certificate
87 nginx-server-configuration-ssl-certificate-key
88 nginx-server-configuration-server-tokens?
b05e8ee1 89 nginx-server-configuration-raw-content
e4b729f8
CB
90
91 <nginx-upstream-configuration>
cb341293
CB
92 nginx-upstream-configuration
93 nginx-upstream-configuration?
e4b729f8
CB
94 nginx-upstream-configuration-name
95 nginx-upstream-configuration-servers
96
97 <nginx-location-configuration>
9c557a69
CB
98 nginx-location-configuration
99 nginx-location-configuration?
e4b729f8
CB
100 nginx-location-configuration-uri
101 nginx-location-configuration-body
102
103 <nginx-named-location-configuration>
9c557a69
CB
104 nginx-named-location-configuration
105 nginx-named-location-configuration?
e4b729f8
CB
106 nginx-named-location-configuration-name
107 nginx-named-location-configuration-body
108
24e96431 109 nginx-service
a5130d10
AW
110 nginx-service-type
111
112 fcgiwrap-configuration
113 fcgiwrap-configuration?
64bae723 114 fcgiwrap-service-type
115
116 <php-fpm-configuration>
117 php-fpm-configuration
118 make-php-fpm-configuration
119 php-fpm-configuration?
120 php-fpm-configuration-php
121 php-fpm-configuration-socket
122 php-fpm-configuration-user
123 php-fpm-configuration-group
124 php-fpm-configuration-socket-user
125 php-fpm-configuration-socket-group
126 php-fpm-configuration-pid-file
127 php-fpm-configuration-log-file
128 php-fpm-configuration-process-manager
129 php-fpm-configuration-display-errors
130 php-fpm-configuration-workers-log-file
131 php-fpm-configuration-file
132
133 <php-fpm-dynamic-process-manager-configuration>
134 php-fpm-dynamic-process-manager-configuration
135 make-php-fpm-dynamic-process-manager-configuration
136 php-fpm-dynamic-process-manager-configuration?
137 php-fpm-dynamic-process-manager-configuration-max-children
138 php-fpm-dynamic-process-manager-configuration-start-servers
139 php-fpm-dynamic-process-manager-configuration-min-spare-servers
140 php-fpm-dynamic-process-manager-configuration-max-spare-servers
141
142 <php-fpm-static-process-manager-configuration>
143 php-fpm-static-process-manager-configuration
144 make-php-fpm-static-process-manager-configuration
145 php-fpm-static-process-manager-configuration?
146 php-fpm-static-process-manager-configuration-max-children
147
148 <php-fpm-on-demand-process-manager-configuration>
149 php-fpm-on-demand-process-manager-configuration
150 make-php-fpm-on-demand-process-manager-configuration
151 php-fpm-on-demand-process-manager-configuration?
152 php-fpm-on-demand-process-manager-configuration-max-children
153 php-fpm-on-demand-process-manager-configuration-process-idle-timeout
154
155 php-fpm-service-type
156 nginx-php-location))
58724c48
DT
157
158;;; Commentary:
159;;;
160;;; Web services.
161;;;
162;;; Code:
163
d067e4ba
CB
164(define-record-type* <httpd-module>
165 httpd-module make-httpd-module
166 httpd-module?
167 (name httpd-load-module-name)
168 (file httpd-load-module-file))
169
170;; Default modules for the httpd-service-type, taken from etc/httpd/httpd.conf
171;; file in the httpd package.
172(define %default-httpd-modules
173 (map (match-lambda
174 ((name file)
175 (httpd-module
176 (name name)
177 (file file))))
178 '(("authn_file_module" "modules/mod_authn_file.so")
179 ("authn_core_module" "modules/mod_authn_core.so")
180 ("authz_host_module" "modules/mod_authz_host.so")
181 ("authz_groupfile_module" "modules/mod_authz_groupfile.so")
182 ("authz_user_module" "modules/mod_authz_user.so")
183 ("authz_core_module" "modules/mod_authz_core.so")
184 ("access_compat_module" "modules/mod_access_compat.so")
185 ("auth_basic_module" "modules/mod_auth_basic.so")
186 ("reqtimeout_module" "modules/mod_reqtimeout.so")
187 ("filter_module" "modules/mod_filter.so")
188 ("mime_module" "modules/mod_mime.so")
189 ("log_config_module" "modules/mod_log_config.so")
190 ("env_module" "modules/mod_env.so")
191 ("headers_module" "modules/mod_headers.so")
192 ("setenvif_module" "modules/mod_setenvif.so")
193 ("version_module" "modules/mod_version.so")
194 ("unixd_module" "modules/mod_unixd.so")
195 ("status_module" "modules/mod_status.so")
196 ("autoindex_module" "modules/mod_autoindex.so")
197 ("dir_module" "modules/mod_dir.so")
198 ("alias_module" "modules/mod_alias.so"))))
199
200(define-record-type* <httpd-config-file>
201 httpd-config-file make-httpd-config-file
202 httpd-config-file?
203 (modules httpd-config-file-modules
204 (default %default-httpd-modules))
205 (server-root httpd-config-file-server-root
206 (default httpd))
207 (server-name httpd-config-file-server-name
208 (default #f))
209 (document-root httpd-config-file-document-root
210 (default "/srv/http"))
211 (listen httpd-config-file-listen
212 (default '("80")))
213 (pid-file httpd-config-file-pid-file
214 (default "/var/run/httpd"))
215 (error-log httpd-config-file-error-log
216 (default "/var/log/httpd/error_log"))
217 (user httpd-config-file-user
218 (default "httpd"))
219 (group httpd-config-file-group
220 (default "httpd"))
221 (extra-config httpd-config-file-extra-config
222 (default
223 (list "TypesConfig etc/httpd/mime.types"))))
224
225(define-gexp-compiler (httpd-config-file-compiler
226 (file <httpd-config-file>) system target)
227 (match file
228 (($ <httpd-config-file> load-modules server-root server-name
229 document-root listen pid-file error-log
230 user group extra-config)
231 (gexp->derivation
232 "httpd.conf"
233 #~(call-with-output-file (ungexp output "out")
234 (lambda (port)
235 (display
236 (string-append
237 (ungexp-splicing
238 `(,@(append-map
239 (match-lambda
240 (($ <httpd-module> name module)
241 `("LoadModule " ,name " " ,module "\n")))
242 load-modules)
243 ,@`("ServerRoot " ,server-root "\n")
244 ,@(if server-name
245 `("ServerName " ,server-name "\n")
246 '())
247 ,@`("DocumentRoot " ,document-root "\n")
248 ,@(append-map
249 (lambda (listen-value)
250 `("Listen " ,listen-value "\n"))
251 listen)
252 ,@(if pid-file
253 `("Pidfile " ,pid-file "\n")
254 '())
255 ,@(if error-log
256 `("ErrorLog " ,error-log "\n")
257 '())
258 ,@(if user
259 `("User " ,user "\n")
260 '())
261 ,@(if group
262 `("Group " ,group "\n")
263 '())
264 "\n\n"
265 ,@extra-config)))
266 port)))
267 #:local-build? #t))))
268
269(define-record-type <httpd-virtualhost>
270 (httpd-virtualhost addresses-and-ports contents)
271 httpd-virtualhost?
272 (addresses-and-ports httpd-virtualhost-addresses-and-ports)
273 (contents httpd-virtualhost-contents))
274
275(define-record-type* <httpd-configuration>
276 httpd-configuration make-httpd-configuration
277 httpd-configuration?
278 (package httpd-configuration-package
279 (default httpd))
280 (pid-file httpd-configuration-pid-file
281 (default "/var/run/httpd"))
282 (config httpd-configuration-config
283 (default (httpd-config-file))))
284
285(define %httpd-accounts
286 (list (user-group (name "httpd") (system? #t))
287 (user-account
288 (name "httpd")
289 (group "httpd")
290 (system? #t)
291 (comment "Apache HTTPD server user")
292 (home-directory "/var/empty")
293 (shell (file-append shadow "/sbin/nologin")))))
294
295(define httpd-shepherd-services
296 (match-lambda
297 (($ <httpd-configuration> package pid-file config)
298 (list (shepherd-service
299 (provision '(httpd))
300 (documentation "The Apache HTTP Server")
301 (requirement '(networking))
302 (start #~(make-forkexec-constructor
303 `(#$(file-append package "/bin/httpd")
304 #$@(if config
305 (list "-f" config)
306 '()))
307 #:pid-file #$pid-file))
308 (stop #~(make-kill-destructor)))))))
309
310(define httpd-activation
311 (match-lambda
312 (($ <httpd-configuration> package pid-file config)
313 (match-record
314 config
315 <httpd-config-file>
316 (error-log document-root)
317 #~(begin
318 (use-modules (guix build utils))
319
320 (mkdir-p #$(dirname error-log))
321 (mkdir-p #$document-root))))))
322
323(define (httpd-process-extensions original-config extension-configs)
324 (let ((config (httpd-configuration-config
325 original-config)))
326 (if (httpd-config-file? config)
327 (httpd-configuration
328 (inherit original-config)
329 (config
330 (httpd-config-file
331 (inherit config)
332 (extra-config
333 (append (httpd-config-file-extra-config config)
334 (append-map
335 (match-lambda
336 (($ <httpd-virtualhost>
337 addresses-and-ports
338 contents)
339 `(,(string-append
340 "<VirtualHost " addresses-and-ports ">\n")
341 ,@contents
342 "\n</VirtualHost>\n"))
343 ((? string? x)
344 `("\n" ,x "\n"))
345 ((? list? x)
346 `("\n" ,@x "\n")))
347 extension-configs)))))))))
348
349(define httpd-service-type
350 (service-type (name 'httpd)
351 (extensions
352 (list (service-extension shepherd-root-service-type
353 httpd-shepherd-services)
354 (service-extension activation-service-type
355 httpd-activation)
356 (service-extension account-service-type
357 (const %httpd-accounts))))
358 (compose concatenate)
359 (extend httpd-process-extensions)
360 (default-value
361 (httpd-configuration))))
362
3b9b12ef
JL
363(define-record-type* <nginx-server-configuration>
364 nginx-server-configuration make-nginx-server-configuration
365 nginx-server-configuration?
8b223cea
CL
366 (listen nginx-server-configuration-listen
367 (default '("80" "443 ssl")))
3b9b12ef 368 (server-name nginx-server-configuration-server-name
8c00b838 369 (default (list 'default)))
3b9b12ef 370 (root nginx-server-configuration-root
8c00b838 371 (default "/srv/http"))
9c557a69
CB
372 (locations nginx-server-configuration-locations
373 (default '()))
3b9b12ef 374 (index nginx-server-configuration-index
8c00b838 375 (default (list "index.html")))
4d14808a
OP
376 (try-files nginx-server-configuration-try-files
377 (default '()))
3b9b12ef 378 (ssl-certificate nginx-server-configuration-ssl-certificate
c48aa70a 379 (default #f))
3b9b12ef 380 (ssl-certificate-key nginx-server-configuration-ssl-certificate-key
c48aa70a 381 (default #f))
3b9b12ef 382 (server-tokens? nginx-server-configuration-server-tokens?
b05e8ee1
CL
383 (default #f))
384 (raw-content nginx-server-configuration-raw-content
385 (default '())))
8c00b838 386
cb341293
CB
387(define-record-type* <nginx-upstream-configuration>
388 nginx-upstream-configuration make-nginx-upstream-configuration
389 nginx-upstream-configuration?
390 (name nginx-upstream-configuration-name)
391 (servers nginx-upstream-configuration-servers))
392
9c557a69
CB
393(define-record-type* <nginx-location-configuration>
394 nginx-location-configuration make-nginx-location-configuration
395 nginx-location-configuration?
396 (uri nginx-location-configuration-uri
397 (default #f))
398 (body nginx-location-configuration-body))
399
400(define-record-type* <nginx-named-location-configuration>
401 nginx-named-location-configuration make-nginx-named-location-configuration
402 nginx-named-location-configuration?
403 (name nginx-named-location-configuration-name
404 (default #f))
405 (body nginx-named-location-configuration-body))
406
0adfe95a
LC
407(define-record-type* <nginx-configuration>
408 nginx-configuration make-nginx-configuration
409 nginx-configuration?
dc72a7f7
LC
410 (nginx nginx-configuration-nginx ;<package>
411 (default nginx))
412 (log-directory nginx-configuration-log-directory ;string
413 (default "/var/log/nginx"))
414 (run-directory nginx-configuration-run-directory ;string
415 (default "/var/run/nginx"))
416 (server-blocks nginx-configuration-server-blocks
417 (default '())) ;list of <nginx-server-configuration>
418 (upstream-blocks nginx-configuration-upstream-blocks
419 (default '())) ;list of <nginx-upstream-configuration>
2881f852
CB
420 (server-names-hash-bucket-size nginx-configuration-server-names-hash-bucket-size
421 (default #f))
422 (server-names-hash-bucket-max-size nginx-configuration-server-names-hash-bucket-max-size
423 (default #f))
dc72a7f7
LC
424 (file nginx-configuration-file ;#f | string | file-like
425 (default #f)))
0adfe95a 426
8c00b838
JL
427(define (config-domain-strings names)
428 "Return a string denoting the nginx config representation of NAMES, a list
429of domain names."
c9aa261b 430 (map (match-lambda
4e9ae301 431 ('default "_ ")
c9aa261b
AW
432 ((? string? str) (list str " ")))
433 names))
8c00b838
JL
434
435(define (config-index-strings names)
436 "Return a string denoting the nginx config representation of NAMES, a list
437of index files."
c9aa261b
AW
438 (map (match-lambda
439 ((? string? str) (list str " ")))
440 names))
8c00b838 441
c9aa261b 442(define emit-nginx-location-config
9c557a69
CB
443 (match-lambda
444 (($ <nginx-location-configuration> uri body)
c9aa261b 445 (list
9c557a69 446 " location " uri " {\n"
c9aa261b 447 (map (lambda (x) (list " " x "\n")) body)
9c557a69
CB
448 " }\n"))
449 (($ <nginx-named-location-configuration> name body)
c9aa261b 450 (list
9c557a69 451 " location @" name " {\n"
c9aa261b 452 (map (lambda (x) (list " " x "\n")) body)
9c557a69
CB
453 " }\n"))))
454
c9aa261b 455(define (emit-nginx-server-config server)
8b223cea 456 (let ((listen (nginx-server-configuration-listen server))
c9aa261b
AW
457 (server-name (nginx-server-configuration-server-name server))
458 (ssl-certificate (nginx-server-configuration-ssl-certificate server))
459 (ssl-certificate-key
460 (nginx-server-configuration-ssl-certificate-key server))
461 (root (nginx-server-configuration-root server))
462 (index (nginx-server-configuration-index server))
4d14808a 463 (try-files (nginx-server-configuration-try-files server))
c9aa261b 464 (server-tokens? (nginx-server-configuration-server-tokens? server))
b05e8ee1
CL
465 (locations (nginx-server-configuration-locations server))
466 (raw-content (nginx-server-configuration-raw-content server)))
c9aa261b
AW
467 (define-syntax-parameter <> (syntax-rules ()))
468 (define-syntax-rule (and/l x tail ...)
469 (let ((x* x))
470 (if x*
471 (syntax-parameterize ((<> (identifier-syntax x*)))
472 (list tail ...))
473 '())))
474 (list
475 " server {\n"
8b223cea 476 (map (lambda (directive) (list " listen " directive ";\n")) listen)
c9aa261b
AW
477 " server_name " (config-domain-strings server-name) ";\n"
478 (and/l ssl-certificate " ssl_certificate " <> ";\n")
479 (and/l ssl-certificate-key " ssl_certificate_key " <> ";\n")
480 " root " root ";\n"
481 " index " (config-index-strings index) ";\n"
4d14808a
OP
482 (if (not (nil? try-files))
483 (and/l (config-index-strings try-files) " try_files " <> ";\n")
484 "")
c9aa261b
AW
485 " server_tokens " (if server-tokens? "on" "off") ";\n"
486 "\n"
487 (map emit-nginx-location-config locations)
488 "\n"
b05e8ee1 489 (map (lambda (x) (list " " x "\n")) raw-content)
c9aa261b 490 " }\n")))
cb341293 491
c9aa261b
AW
492(define (emit-nginx-upstream-config upstream)
493 (list
cb341293 494 " upstream " (nginx-upstream-configuration-name upstream) " {\n"
c9aa261b
AW
495 (map (lambda (server)
496 (simple-format #f " server ~A;\n" server))
497 (nginx-upstream-configuration-servers upstream))
8c00b838
JL
498 " }\n"))
499
c9aa261b
AW
500(define (flatten . lst)
501 "Return a list that recursively concatenates all sub-lists of LST."
502 (define (flatten1 head out)
503 (if (list? head)
504 (fold-right flatten1 out head)
505 (cons head out)))
506 (fold-right flatten1 '() lst))
507
472368a8
CB
508(define (default-nginx-config config)
509 (match-record config
510 <nginx-configuration>
511 (nginx log-directory run-directory
512 server-blocks upstream-blocks
513 server-names-hash-bucket-size
514 server-names-hash-bucket-max-size)
515 (apply mixed-text-file "nginx.conf"
516 (flatten
517 "user nginx nginx;\n"
518 "pid " run-directory "/pid;\n"
519 "error_log " log-directory "/error.log info;\n"
520 "http {\n"
521 " client_body_temp_path " run-directory "/client_body_temp;\n"
522 " proxy_temp_path " run-directory "/proxy_temp;\n"
523 " fastcgi_temp_path " run-directory "/fastcgi_temp;\n"
524 " uwsgi_temp_path " run-directory "/uwsgi_temp;\n"
525 " scgi_temp_path " run-directory "/scgi_temp;\n"
526 " access_log " log-directory "/access.log;\n"
527 " include " nginx "/share/nginx/conf/mime.types;\n"
528 (if server-names-hash-bucket-size
529 (string-append
530 " server_names_hash_bucket_size "
531 (number->string server-names-hash-bucket-size)
532 ";\n")
533 "")
534 (if server-names-hash-bucket-max-size
535 (string-append
536 " server_names_hash_bucket_max_size "
537 (number->string server-names-hash-bucket-max-size)
538 ";\n")
539 "")
540 "\n"
541 (map emit-nginx-upstream-config upstream-blocks)
542 (map emit-nginx-server-config server-blocks)
543 "}\n"
544 "events {}\n"))))
58724c48 545
0adfe95a
LC
546(define %nginx-accounts
547 (list (user-group (name "nginx") (system? #t))
548 (user-account
549 (name "nginx")
550 (group "nginx")
551 (system? #t)
552 (comment "nginx server user")
553 (home-directory "/var/empty")
9e41130b 554 (shell (file-append shadow "/sbin/nologin")))))
0adfe95a 555
472368a8
CB
556(define (nginx-activation config)
557 (match-record config
558 <nginx-configuration>
559 (nginx log-directory run-directory file)
560 #~(begin
561 (use-modules (guix build utils))
0adfe95a 562
472368a8
CB
563 (format #t "creating nginx log directory '~a'~%" #$log-directory)
564 (mkdir-p #$log-directory)
565 (format #t "creating nginx run directory '~a'~%" #$run-directory)
566 (mkdir-p #$run-directory)
567 (format #t "creating nginx temp directories '~a/{client_body,proxy,fastcgi,uwsgi,scgi}_temp'~%" #$run-directory)
568 (mkdir-p (string-append #$run-directory "/client_body_temp"))
569 (mkdir-p (string-append #$run-directory "/proxy_temp"))
570 (mkdir-p (string-append #$run-directory "/fastcgi_temp"))
571 (mkdir-p (string-append #$run-directory "/uwsgi_temp"))
572 (mkdir-p (string-append #$run-directory "/scgi_temp"))
573 ;; Start-up logs. Once configuration is loaded, nginx switches to
574 ;; log-directory.
575 (mkdir-p (string-append #$run-directory "/logs"))
576 ;; Check configuration file syntax.
577 (system* (string-append #$nginx "/sbin/nginx")
578 "-c" #$(or file
579 (default-nginx-config config))
580 "-t"))))
0adfe95a 581
472368a8
CB
582(define (nginx-shepherd-service config)
583 (match-record config
584 <nginx-configuration>
585 (nginx file run-directory)
586 (let* ((nginx-binary (file-append nginx "/sbin/nginx"))
587 (nginx-action
588 (lambda args
589 #~(lambda _
590 (zero?
591 (system* #$nginx-binary "-c"
592 #$(or file
593 (default-nginx-config config))
594 #$@args))))))
0adfe95a 595
472368a8
CB
596 ;; TODO: Add 'reload' action.
597 (list (shepherd-service
598 (provision '(nginx))
599 (documentation "Run the nginx daemon.")
600 (requirement '(user-processes loopback))
601 (start (nginx-action "-p" run-directory))
602 (stop (nginx-action "-s" "stop")))))))
0adfe95a
LC
603
604(define nginx-service-type
605 (service-type (name 'nginx)
606 (extensions
d4053c71
AK
607 (list (service-extension shepherd-root-service-type
608 nginx-shepherd-service)
0adfe95a
LC
609 (service-extension activation-service-type
610 nginx-activation)
611 (service-extension account-service-type
d338237d
JL
612 (const %nginx-accounts))))
613 (compose concatenate)
614 (extend (lambda (config servers)
615 (nginx-configuration
616 (inherit config)
617 (server-blocks
618 (append (nginx-configuration-server-blocks config)
ad4cc435
CB
619 servers)))))
620 (default-value
621 (nginx-configuration))))
0adfe95a 622
a5130d10
AW
623(define-record-type* <fcgiwrap-configuration> fcgiwrap-configuration
624 make-fcgiwrap-configuration
625 fcgiwrap-configuration?
626 (package fcgiwrap-configuration-package ;<package>
627 (default fcgiwrap))
628 (socket fcgiwrap-configuration-socket
629 (default "tcp:127.0.0.1:9000"))
630 (user fcgiwrap-configuration-user
631 (default "fcgiwrap"))
632 (group fcgiwrap-configuration-group
633 (default "fcgiwrap")))
634
635(define fcgiwrap-accounts
636 (match-lambda
637 (($ <fcgiwrap-configuration> package socket user group)
638 (filter identity
639 (list
640 (and (equal? group "fcgiwrap")
641 (user-group
642 (name "fcgiwrap")
643 (system? #t)))
644 (and (equal? user "fcgiwrap")
645 (user-account
646 (name "fcgiwrap")
647 (group group)
648 (system? #t)
649 (comment "Fcgiwrap Daemon")
650 (home-directory "/var/empty")
651 (shell (file-append shadow "/sbin/nologin")))))))))
652
653(define fcgiwrap-shepherd-service
654 (match-lambda
655 (($ <fcgiwrap-configuration> package socket user group)
656 (list (shepherd-service
657 (provision '(fcgiwrap))
658 (documentation "Run the fcgiwrap daemon.")
659 (requirement '(networking))
660 (start #~(make-forkexec-constructor
661 '(#$(file-append package "/sbin/fcgiwrap")
662 "-s" #$socket)
663 #:user #$user #:group #$group))
664 (stop #~(make-kill-destructor)))))))
665
666(define fcgiwrap-service-type
667 (service-type (name 'fcgiwrap)
668 (extensions
669 (list (service-extension shepherd-root-service-type
670 fcgiwrap-shepherd-service)
671 (service-extension account-service-type
672 fcgiwrap-accounts)))
673 (default-value (fcgiwrap-configuration))))
64bae723 674
675(define-record-type* <php-fpm-configuration> php-fpm-configuration
676 make-php-fpm-configuration
677 php-fpm-configuration?
678 (php php-fpm-configuration-php ;<package>
679 (default php))
680 (socket php-fpm-configuration-socket
681 (default (string-append "/var/run/php"
682 (version-major (package-version php))
683 "-fpm.sock")))
684 (user php-fpm-configuration-user
685 (default "php-fpm"))
686 (group php-fpm-configuration-group
687 (default "php-fpm"))
688 (socket-user php-fpm-configuration-socket-user
689 (default "php-fpm"))
690 (socket-group php-fpm-configuration-socket-group
691 (default "nginx"))
692 (pid-file php-fpm-configuration-pid-file
693 (default (string-append "/var/run/php"
694 (version-major (package-version php))
695 "-fpm.pid")))
696 (log-file php-fpm-configuration-log-file
697 (default (string-append "/var/log/php"
698 (version-major (package-version php))
699 "-fpm.log")))
700 (process-manager php-fpm-configuration-process-manager
701 (default (php-fpm-dynamic-process-manager-configuration)))
702 (display-errors php-fpm-configuration-display-errors
703 (default #f))
704 (workers-log-file php-fpm-configuration-workers-log-file
705 (default (string-append "/var/log/php"
706 (version-major (package-version php))
707 "-fpm.www.log")))
708 (file php-fpm-configuration-file ;#f | file-like
709 (default #f)))
710
711(define-record-type* <php-fpm-dynamic-process-manager-configuration>
712 php-fpm-dynamic-process-manager-configuration
713 make-php-fpm-dynamic-process-manager-configuration
714 php-fpm-dynamic-process-manager-configuration?
715 (max-children php-fpm-dynamic-process-manager-configuration-max-children
716 (default 5))
717 (start-servers php-fpm-dynamic-process-manager-configuration-start-servers
718 (default 2))
719 (min-spare-servers php-fpm-dynamic-process-manager-configuration-min-spare-servers
720 (default 1))
721 (max-spare-servers php-fpm-dynamic-process-manager-configuration-max-spare-servers
722 (default 3)))
723
724(define-record-type* <php-fpm-static-process-manager-configuration>
725 php-fpm-static-process-manager-configuration
726 make-php-fpm-static-process-manager-configuration
727 php-fpm-static-process-manager-configuration?
728 (max-children php-fpm-static-process-manager-configuration-max-children
729 (default 5)))
730
731(define-record-type* <php-fpm-on-demand-process-manager-configuration>
732 php-fpm-on-demand-process-manager-configuration
733 make-php-fpm-on-demand-process-manager-configuration
734 php-fpm-on-demand-process-manager-configuration?
735 (max-children php-fpm-on-demand-process-manager-configuration-max-children
736 (default 5))
737 (process-idle-timeout php-fpm-on-demand-process-manager-configuration-process-idle-timeout
738 (default 10)))
739
740(define php-fpm-accounts
741 (match-lambda
742 (($ <php-fpm-configuration> php socket user group socket-user socket-group _ _ _ _ _ _)
743 (list
744 (user-group (name "php-fpm") (system? #t))
745 (user-group
746 (name group)
747 (system? #t))
748 (user-account
749 (name user)
750 (group group)
751 (supplementary-groups '("php-fpm"))
752 (system? #t)
753 (comment "php-fpm daemon user")
754 (home-directory "/var/empty")
755 (shell (file-append shadow "/sbin/nologin")))))))
756
757(define (default-php-fpm-config socket user group socket-user socket-group
758 pid-file log-file pm display-errors workers-log-file)
759 (apply mixed-text-file "php-fpm.conf"
760 (flatten
761 "[global]\n"
762 "pid =" pid-file "\n"
763 "error_log =" log-file "\n"
764 "[www]\n"
765 "user =" user "\n"
766 "group =" group "\n"
767 "listen =" socket "\n"
768 "listen.owner =" socket-user "\n"
769 "listen.group =" socket-group "\n"
770
771 (match pm
772 (($ <php-fpm-dynamic-process-manager-configuration>
773 pm.max-children
774 pm.start-servers
775 pm.min-spare-servers
776 pm.max-spare-servers)
777 (list
778 "pm = dynamic\n"
779 "pm.max_children =" (number->string pm.max-children) "\n"
780 "pm.start_servers =" (number->string pm.start-servers) "\n"
781 "pm.min_spare_servers =" (number->string pm.min-spare-servers) "\n"
782 "pm.max_spare_servers =" (number->string pm.max-spare-servers) "\n"))
783
784 (($ <php-fpm-static-process-manager-configuration>
785 pm.max-children)
786 (list
787 "pm = static\n"
788 "pm.max_children =" (number->string pm.max-children) "\n"))
789
790 (($ <php-fpm-on-demand-process-manager-configuration>
791 pm.max-children
792 pm.process-idle-timeout)
793 (list
794 "pm = ondemand\n"
795 "pm.max_children =" (number->string pm.max-children) "\n"
796 "pm.process_idle_timeout =" (number->string pm.process-idle-timeout) "s\n")))
797
798
799 "php_flag[display_errors] = " (if display-errors "on" "off") "\n"
800
801 (if workers-log-file
802 (list "catch_workers_output = yes\n"
803 "php_admin_value[error_log] =" workers-log-file "\n"
804 "php_admin_flag[log_errors] = on\n")
805 (list "catch_workers_output = no\n")))))
806
807(define php-fpm-shepherd-service
808 (match-lambda
809 (($ <php-fpm-configuration> php socket user group socket-user socket-group
810 pid-file log-file pm display-errors workers-log-file file)
811 (list (shepherd-service
812 (provision '(php-fpm))
813 (documentation "Run the php-fpm daemon.")
814 (requirement '(networking))
815 (start #~(make-forkexec-constructor
816 '(#$(file-append php "/sbin/php-fpm")
817 "--fpm-config"
818 #$(or file
819 (default-php-fpm-config socket user group
820 socket-user socket-group pid-file log-file
821 pm display-errors workers-log-file)))
822 #:pid-file #$pid-file))
823 (stop #~(make-kill-destructor)))))))
824
825(define php-fpm-activation
826 (match-lambda
827 (($ <php-fpm-configuration> _ _ user _ _ _ _ log-file _ _ workers-log-file _)
828 #~(begin
829 (use-modules (guix build utils))
830 (let* ((user (getpwnam #$user))
831 (touch (lambda (file-name)
832 (call-with-output-file file-name (const #t))))
833 (init-log-file
834 (lambda (file-name)
835 (when #$workers-log-file
836 (when (not (file-exists? file-name))
837 (touch file-name))
838 (chown file-name (passwd:uid user) (passwd:gid user))
839 (chmod file-name #o660)))))
840 (init-log-file #$log-file)
841 (init-log-file #$workers-log-file))))))
842
843
844(define php-fpm-service-type
845 (service-type
846 (name 'php-fpm)
847 (description
848 "Run @command{php-fpm} to provide a fastcgi socket for calling php through
849a webserver.")
850 (extensions
851 (list (service-extension shepherd-root-service-type
852 php-fpm-shepherd-service)
853 (service-extension activation-service-type
854 php-fpm-activation)
855 (service-extension account-service-type
856 php-fpm-accounts)))
857 (default-value (php-fpm-configuration))))
858
859(define* (nginx-php-location
860 #:key
861 (nginx-package nginx)
862 (socket (string-append "/var/run/php"
863 (version-major (package-version php))
864 "-fpm.sock")))
865 "Return a nginx-location-configuration that makes nginx run .php files."
866 (nginx-location-configuration
867 (uri "~ \\.php$")
868 (body (list
869 "fastcgi_split_path_info ^(.+\\.php)(/.+)$;"
870 (string-append "fastcgi_pass unix:" socket ";")
871 "fastcgi_index index.php;"
872 (list "include " nginx-package "/share/nginx/conf/fastcgi.conf;")))))