web.scm 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2015 David Thompson <davet@gnu.org>
  3. ;;; Copyright © 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
  4. ;;; Copyright © 2016 ng0 <ng0@we.make.ritual.n0.is>
  5. ;;; Copyright © 2016, 2017 Julien Lepiller <julien@lepiller.eu>
  6. ;;; Copyright © 2017 Christopher Baines <mail@cbaines.net>
  7. ;;; Copyright © 2017 nee <nee-git@hidamari.blue>
  8. ;;; Copyright © 2017 Clément Lassieur <clement@lassieur.org>
  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. (define-module (gnu services web)
  25. #:use-module (gnu services)
  26. #:use-module (gnu services shepherd)
  27. #:use-module (gnu system shadow)
  28. #:use-module (gnu packages admin)
  29. #:use-module (gnu packages web)
  30. #:use-module (gnu packages php)
  31. #:use-module (guix records)
  32. #:use-module (guix gexp)
  33. #:use-module ((guix utils) #:select (version-major))
  34. #:use-module ((guix packages) #:select (package-version))
  35. #:use-module (srfi srfi-1)
  36. #:use-module (ice-9 match)
  37. #:export (<nginx-configuration>
  38. nginx-configuration
  39. nginx-configuration?
  40. nginx-configuartion-nginx
  41. nginx-configuration-log-directory
  42. nginx-configuration-run-directory
  43. nginx-configuration-server-blocks
  44. nginx-configuration-upstream-blocks
  45. nginx-configuration-server-names-hash-bucket-size
  46. nginx-configuration-server-names-hash-bucket-max-size
  47. nginx-configuration-file
  48. <nginx-server-configuration>
  49. nginx-server-configuration
  50. nginx-server-configuration?
  51. nginx-server-configuration-listen
  52. nginx-server-configuration-server-name
  53. nginx-server-configuration-root
  54. nginx-server-configuration-locations
  55. nginx-server-configuration-index
  56. nginx-server-configuration-ssl-certificate
  57. nginx-server-configuration-ssl-certificate-key
  58. nginx-server-configuration-server-tokens?
  59. nginx-server-configuration-raw-content
  60. <nginx-upstream-configuration>
  61. nginx-upstream-configuration
  62. nginx-upstream-configuration?
  63. nginx-upstream-configuration-name
  64. nginx-upstream-configuration-servers
  65. <nginx-location-configuration>
  66. nginx-location-configuration
  67. nginx-location-configuration?
  68. nginx-location-configuration-uri
  69. nginx-location-configuration-body
  70. <nginx-named-location-configuration>
  71. nginx-named-location-configuration
  72. nginx-named-location-configuration?
  73. nginx-named-location-configuration-name
  74. nginx-named-location-configuration-body
  75. nginx-service
  76. nginx-service-type
  77. fcgiwrap-configuration
  78. fcgiwrap-configuration?
  79. fcgiwrap-service-type
  80. <php-fpm-configuration>
  81. php-fpm-configuration
  82. make-php-fpm-configuration
  83. php-fpm-configuration?
  84. php-fpm-configuration-php
  85. php-fpm-configuration-socket
  86. php-fpm-configuration-user
  87. php-fpm-configuration-group
  88. php-fpm-configuration-socket-user
  89. php-fpm-configuration-socket-group
  90. php-fpm-configuration-pid-file
  91. php-fpm-configuration-log-file
  92. php-fpm-configuration-process-manager
  93. php-fpm-configuration-display-errors
  94. php-fpm-configuration-workers-log-file
  95. php-fpm-configuration-file
  96. <php-fpm-dynamic-process-manager-configuration>
  97. php-fpm-dynamic-process-manager-configuration
  98. make-php-fpm-dynamic-process-manager-configuration
  99. php-fpm-dynamic-process-manager-configuration?
  100. php-fpm-dynamic-process-manager-configuration-max-children
  101. php-fpm-dynamic-process-manager-configuration-start-servers
  102. php-fpm-dynamic-process-manager-configuration-min-spare-servers
  103. php-fpm-dynamic-process-manager-configuration-max-spare-servers
  104. <php-fpm-static-process-manager-configuration>
  105. php-fpm-static-process-manager-configuration
  106. make-php-fpm-static-process-manager-configuration
  107. php-fpm-static-process-manager-configuration?
  108. php-fpm-static-process-manager-configuration-max-children
  109. <php-fpm-on-demand-process-manager-configuration>
  110. php-fpm-on-demand-process-manager-configuration
  111. make-php-fpm-on-demand-process-manager-configuration
  112. php-fpm-on-demand-process-manager-configuration?
  113. php-fpm-on-demand-process-manager-configuration-max-children
  114. php-fpm-on-demand-process-manager-configuration-process-idle-timeout
  115. php-fpm-service-type
  116. nginx-php-location))
  117. ;;; Commentary:
  118. ;;;
  119. ;;; Web services.
  120. ;;;
  121. ;;; Code:
  122. (define-record-type* <nginx-server-configuration>
  123. nginx-server-configuration make-nginx-server-configuration
  124. nginx-server-configuration?
  125. (listen nginx-server-configuration-listen
  126. (default '("80" "443 ssl")))
  127. (server-name nginx-server-configuration-server-name
  128. (default (list 'default)))
  129. (root nginx-server-configuration-root
  130. (default "/srv/http"))
  131. (locations nginx-server-configuration-locations
  132. (default '()))
  133. (index nginx-server-configuration-index
  134. (default (list "index.html")))
  135. (try-files nginx-server-configuration-try-files
  136. (default '()))
  137. (ssl-certificate nginx-server-configuration-ssl-certificate
  138. (default #f))
  139. (ssl-certificate-key nginx-server-configuration-ssl-certificate-key
  140. (default #f))
  141. (server-tokens? nginx-server-configuration-server-tokens?
  142. (default #f))
  143. (raw-content nginx-server-configuration-raw-content
  144. (default '())))
  145. (define-record-type* <nginx-upstream-configuration>
  146. nginx-upstream-configuration make-nginx-upstream-configuration
  147. nginx-upstream-configuration?
  148. (name nginx-upstream-configuration-name)
  149. (servers nginx-upstream-configuration-servers))
  150. (define-record-type* <nginx-location-configuration>
  151. nginx-location-configuration make-nginx-location-configuration
  152. nginx-location-configuration?
  153. (uri nginx-location-configuration-uri
  154. (default #f))
  155. (body nginx-location-configuration-body))
  156. (define-record-type* <nginx-named-location-configuration>
  157. nginx-named-location-configuration make-nginx-named-location-configuration
  158. nginx-named-location-configuration?
  159. (name nginx-named-location-configuration-name
  160. (default #f))
  161. (body nginx-named-location-configuration-body))
  162. (define-record-type* <nginx-configuration>
  163. nginx-configuration make-nginx-configuration
  164. nginx-configuration?
  165. (nginx nginx-configuration-nginx ;<package>
  166. (default nginx))
  167. (log-directory nginx-configuration-log-directory ;string
  168. (default "/var/log/nginx"))
  169. (run-directory nginx-configuration-run-directory ;string
  170. (default "/var/run/nginx"))
  171. (server-blocks nginx-configuration-server-blocks
  172. (default '())) ;list of <nginx-server-configuration>
  173. (upstream-blocks nginx-configuration-upstream-blocks
  174. (default '())) ;list of <nginx-upstream-configuration>
  175. (server-names-hash-bucket-size nginx-configuration-server-names-hash-bucket-size
  176. (default #f))
  177. (server-names-hash-bucket-max-size nginx-configuration-server-names-hash-bucket-max-size
  178. (default #f))
  179. (file nginx-configuration-file ;#f | string | file-like
  180. (default #f)))
  181. (define (config-domain-strings names)
  182. "Return a string denoting the nginx config representation of NAMES, a list
  183. of domain names."
  184. (map (match-lambda
  185. ('default "_ ")
  186. ((? string? str) (list str " ")))
  187. names))
  188. (define (config-index-strings names)
  189. "Return a string denoting the nginx config representation of NAMES, a list
  190. of index files."
  191. (map (match-lambda
  192. ((? string? str) (list str " ")))
  193. names))
  194. (define emit-nginx-location-config
  195. (match-lambda
  196. (($ <nginx-location-configuration> uri body)
  197. (list
  198. " location " uri " {\n"
  199. (map (lambda (x) (list " " x "\n")) body)
  200. " }\n"))
  201. (($ <nginx-named-location-configuration> name body)
  202. (list
  203. " location @" name " {\n"
  204. (map (lambda (x) (list " " x "\n")) body)
  205. " }\n"))))
  206. (define (emit-nginx-server-config server)
  207. (let ((listen (nginx-server-configuration-listen server))
  208. (server-name (nginx-server-configuration-server-name server))
  209. (ssl-certificate (nginx-server-configuration-ssl-certificate server))
  210. (ssl-certificate-key
  211. (nginx-server-configuration-ssl-certificate-key server))
  212. (root (nginx-server-configuration-root server))
  213. (index (nginx-server-configuration-index server))
  214. (try-files (nginx-server-configuration-try-files server))
  215. (server-tokens? (nginx-server-configuration-server-tokens? server))
  216. (locations (nginx-server-configuration-locations server))
  217. (raw-content (nginx-server-configuration-raw-content server)))
  218. (define-syntax-parameter <> (syntax-rules ()))
  219. (define-syntax-rule (and/l x tail ...)
  220. (let ((x* x))
  221. (if x*
  222. (syntax-parameterize ((<> (identifier-syntax x*)))
  223. (list tail ...))
  224. '())))
  225. (list
  226. " server {\n"
  227. (map (lambda (directive) (list " listen " directive ";\n")) listen)
  228. " server_name " (config-domain-strings server-name) ";\n"
  229. (and/l ssl-certificate " ssl_certificate " <> ";\n")
  230. (and/l ssl-certificate-key " ssl_certificate_key " <> ";\n")
  231. " root " root ";\n"
  232. " index " (config-index-strings index) ";\n"
  233. (if (not (nil? try-files))
  234. (and/l (config-index-strings try-files) " try_files " <> ";\n")
  235. "")
  236. " server_tokens " (if server-tokens? "on" "off") ";\n"
  237. "\n"
  238. (map emit-nginx-location-config locations)
  239. "\n"
  240. (map (lambda (x) (list " " x "\n")) raw-content)
  241. " }\n")))
  242. (define (emit-nginx-upstream-config upstream)
  243. (list
  244. " upstream " (nginx-upstream-configuration-name upstream) " {\n"
  245. (map (lambda (server)
  246. (simple-format #f " server ~A;\n" server))
  247. (nginx-upstream-configuration-servers upstream))
  248. " }\n"))
  249. (define (flatten . lst)
  250. "Return a list that recursively concatenates all sub-lists of LST."
  251. (define (flatten1 head out)
  252. (if (list? head)
  253. (fold-right flatten1 out head)
  254. (cons head out)))
  255. (fold-right flatten1 '() lst))
  256. (define (default-nginx-config config)
  257. (match-record config
  258. <nginx-configuration>
  259. (nginx log-directory run-directory
  260. server-blocks upstream-blocks
  261. server-names-hash-bucket-size
  262. server-names-hash-bucket-max-size)
  263. (apply mixed-text-file "nginx.conf"
  264. (flatten
  265. "user nginx nginx;\n"
  266. "pid " run-directory "/pid;\n"
  267. "error_log " log-directory "/error.log info;\n"
  268. "http {\n"
  269. " client_body_temp_path " run-directory "/client_body_temp;\n"
  270. " proxy_temp_path " run-directory "/proxy_temp;\n"
  271. " fastcgi_temp_path " run-directory "/fastcgi_temp;\n"
  272. " uwsgi_temp_path " run-directory "/uwsgi_temp;\n"
  273. " scgi_temp_path " run-directory "/scgi_temp;\n"
  274. " access_log " log-directory "/access.log;\n"
  275. " include " nginx "/share/nginx/conf/mime.types;\n"
  276. (if server-names-hash-bucket-size
  277. (string-append
  278. " server_names_hash_bucket_size "
  279. (number->string server-names-hash-bucket-size)
  280. ";\n")
  281. "")
  282. (if server-names-hash-bucket-max-size
  283. (string-append
  284. " server_names_hash_bucket_max_size "
  285. (number->string server-names-hash-bucket-max-size)
  286. ";\n")
  287. "")
  288. "\n"
  289. (map emit-nginx-upstream-config upstream-blocks)
  290. (map emit-nginx-server-config server-blocks)
  291. "}\n"
  292. "events {}\n"))))
  293. (define %nginx-accounts
  294. (list (user-group (name "nginx") (system? #t))
  295. (user-account
  296. (name "nginx")
  297. (group "nginx")
  298. (system? #t)
  299. (comment "nginx server user")
  300. (home-directory "/var/empty")
  301. (shell (file-append shadow "/sbin/nologin")))))
  302. (define (nginx-activation config)
  303. (match-record config
  304. <nginx-configuration>
  305. (nginx log-directory run-directory file)
  306. #~(begin
  307. (use-modules (guix build utils))
  308. (format #t "creating nginx log directory '~a'~%" #$log-directory)
  309. (mkdir-p #$log-directory)
  310. (format #t "creating nginx run directory '~a'~%" #$run-directory)
  311. (mkdir-p #$run-directory)
  312. (format #t "creating nginx temp directories '~a/{client_body,proxy,fastcgi,uwsgi,scgi}_temp'~%" #$run-directory)
  313. (mkdir-p (string-append #$run-directory "/client_body_temp"))
  314. (mkdir-p (string-append #$run-directory "/proxy_temp"))
  315. (mkdir-p (string-append #$run-directory "/fastcgi_temp"))
  316. (mkdir-p (string-append #$run-directory "/uwsgi_temp"))
  317. (mkdir-p (string-append #$run-directory "/scgi_temp"))
  318. ;; Start-up logs. Once configuration is loaded, nginx switches to
  319. ;; log-directory.
  320. (mkdir-p (string-append #$run-directory "/logs"))
  321. ;; Check configuration file syntax.
  322. (system* (string-append #$nginx "/sbin/nginx")
  323. "-c" #$(or file
  324. (default-nginx-config config))
  325. "-t"))))
  326. (define (nginx-shepherd-service config)
  327. (match-record config
  328. <nginx-configuration>
  329. (nginx file run-directory)
  330. (let* ((nginx-binary (file-append nginx "/sbin/nginx"))
  331. (nginx-action
  332. (lambda args
  333. #~(lambda _
  334. (zero?
  335. (system* #$nginx-binary "-c"
  336. #$(or file
  337. (default-nginx-config config))
  338. #$@args))))))
  339. ;; TODO: Add 'reload' action.
  340. (list (shepherd-service
  341. (provision '(nginx))
  342. (documentation "Run the nginx daemon.")
  343. (requirement '(user-processes loopback))
  344. (start (nginx-action "-p" run-directory))
  345. (stop (nginx-action "-s" "stop")))))))
  346. (define nginx-service-type
  347. (service-type (name 'nginx)
  348. (extensions
  349. (list (service-extension shepherd-root-service-type
  350. nginx-shepherd-service)
  351. (service-extension activation-service-type
  352. nginx-activation)
  353. (service-extension account-service-type
  354. (const %nginx-accounts))))
  355. (compose concatenate)
  356. (extend (lambda (config servers)
  357. (nginx-configuration
  358. (inherit config)
  359. (server-blocks
  360. (append (nginx-configuration-server-blocks config)
  361. servers)))))
  362. (default-value
  363. (nginx-configuration))))
  364. (define-record-type* <fcgiwrap-configuration> fcgiwrap-configuration
  365. make-fcgiwrap-configuration
  366. fcgiwrap-configuration?
  367. (package fcgiwrap-configuration-package ;<package>
  368. (default fcgiwrap))
  369. (socket fcgiwrap-configuration-socket
  370. (default "tcp:127.0.0.1:9000"))
  371. (user fcgiwrap-configuration-user
  372. (default "fcgiwrap"))
  373. (group fcgiwrap-configuration-group
  374. (default "fcgiwrap")))
  375. (define fcgiwrap-accounts
  376. (match-lambda
  377. (($ <fcgiwrap-configuration> package socket user group)
  378. (filter identity
  379. (list
  380. (and (equal? group "fcgiwrap")
  381. (user-group
  382. (name "fcgiwrap")
  383. (system? #t)))
  384. (and (equal? user "fcgiwrap")
  385. (user-account
  386. (name "fcgiwrap")
  387. (group group)
  388. (system? #t)
  389. (comment "Fcgiwrap Daemon")
  390. (home-directory "/var/empty")
  391. (shell (file-append shadow "/sbin/nologin")))))))))
  392. (define fcgiwrap-shepherd-service
  393. (match-lambda
  394. (($ <fcgiwrap-configuration> package socket user group)
  395. (list (shepherd-service
  396. (provision '(fcgiwrap))
  397. (documentation "Run the fcgiwrap daemon.")
  398. (requirement '(networking))
  399. (start #~(make-forkexec-constructor
  400. '(#$(file-append package "/sbin/fcgiwrap")
  401. "-s" #$socket)
  402. #:user #$user #:group #$group))
  403. (stop #~(make-kill-destructor)))))))
  404. (define fcgiwrap-service-type
  405. (service-type (name 'fcgiwrap)
  406. (extensions
  407. (list (service-extension shepherd-root-service-type
  408. fcgiwrap-shepherd-service)
  409. (service-extension account-service-type
  410. fcgiwrap-accounts)))
  411. (default-value (fcgiwrap-configuration))))
  412. (define-record-type* <php-fpm-configuration> php-fpm-configuration
  413. make-php-fpm-configuration
  414. php-fpm-configuration?
  415. (php php-fpm-configuration-php ;<package>
  416. (default php))
  417. (socket php-fpm-configuration-socket
  418. (default (string-append "/var/run/php"
  419. (version-major (package-version php))
  420. "-fpm.sock")))
  421. (user php-fpm-configuration-user
  422. (default "php-fpm"))
  423. (group php-fpm-configuration-group
  424. (default "php-fpm"))
  425. (socket-user php-fpm-configuration-socket-user
  426. (default "php-fpm"))
  427. (socket-group php-fpm-configuration-socket-group
  428. (default "nginx"))
  429. (pid-file php-fpm-configuration-pid-file
  430. (default (string-append "/var/run/php"
  431. (version-major (package-version php))
  432. "-fpm.pid")))
  433. (log-file php-fpm-configuration-log-file
  434. (default (string-append "/var/log/php"
  435. (version-major (package-version php))
  436. "-fpm.log")))
  437. (process-manager php-fpm-configuration-process-manager
  438. (default (php-fpm-dynamic-process-manager-configuration)))
  439. (display-errors php-fpm-configuration-display-errors
  440. (default #f))
  441. (workers-log-file php-fpm-configuration-workers-log-file
  442. (default (string-append "/var/log/php"
  443. (version-major (package-version php))
  444. "-fpm.www.log")))
  445. (file php-fpm-configuration-file ;#f | file-like
  446. (default #f)))
  447. (define-record-type* <php-fpm-dynamic-process-manager-configuration>
  448. php-fpm-dynamic-process-manager-configuration
  449. make-php-fpm-dynamic-process-manager-configuration
  450. php-fpm-dynamic-process-manager-configuration?
  451. (max-children php-fpm-dynamic-process-manager-configuration-max-children
  452. (default 5))
  453. (start-servers php-fpm-dynamic-process-manager-configuration-start-servers
  454. (default 2))
  455. (min-spare-servers php-fpm-dynamic-process-manager-configuration-min-spare-servers
  456. (default 1))
  457. (max-spare-servers php-fpm-dynamic-process-manager-configuration-max-spare-servers
  458. (default 3)))
  459. (define-record-type* <php-fpm-static-process-manager-configuration>
  460. php-fpm-static-process-manager-configuration
  461. make-php-fpm-static-process-manager-configuration
  462. php-fpm-static-process-manager-configuration?
  463. (max-children php-fpm-static-process-manager-configuration-max-children
  464. (default 5)))
  465. (define-record-type* <php-fpm-on-demand-process-manager-configuration>
  466. php-fpm-on-demand-process-manager-configuration
  467. make-php-fpm-on-demand-process-manager-configuration
  468. php-fpm-on-demand-process-manager-configuration?
  469. (max-children php-fpm-on-demand-process-manager-configuration-max-children
  470. (default 5))
  471. (process-idle-timeout php-fpm-on-demand-process-manager-configuration-process-idle-timeout
  472. (default 10)))
  473. (define php-fpm-accounts
  474. (match-lambda
  475. (($ <php-fpm-configuration> php socket user group socket-user socket-group _ _ _ _ _ _)
  476. (list
  477. (user-group (name "php-fpm") (system? #t))
  478. (user-group
  479. (name group)
  480. (system? #t))
  481. (user-account
  482. (name user)
  483. (group group)
  484. (supplementary-groups '("php-fpm"))
  485. (system? #t)
  486. (comment "php-fpm daemon user")
  487. (home-directory "/var/empty")
  488. (shell (file-append shadow "/sbin/nologin")))))))
  489. (define (default-php-fpm-config socket user group socket-user socket-group
  490. pid-file log-file pm display-errors workers-log-file)
  491. (apply mixed-text-file "php-fpm.conf"
  492. (flatten
  493. "[global]\n"
  494. "pid =" pid-file "\n"
  495. "error_log =" log-file "\n"
  496. "[www]\n"
  497. "user =" user "\n"
  498. "group =" group "\n"
  499. "listen =" socket "\n"
  500. "listen.owner =" socket-user "\n"
  501. "listen.group =" socket-group "\n"
  502. (match pm
  503. (($ <php-fpm-dynamic-process-manager-configuration>
  504. pm.max-children
  505. pm.start-servers
  506. pm.min-spare-servers
  507. pm.max-spare-servers)
  508. (list
  509. "pm = dynamic\n"
  510. "pm.max_children =" (number->string pm.max-children) "\n"
  511. "pm.start_servers =" (number->string pm.start-servers) "\n"
  512. "pm.min_spare_servers =" (number->string pm.min-spare-servers) "\n"
  513. "pm.max_spare_servers =" (number->string pm.max-spare-servers) "\n"))
  514. (($ <php-fpm-static-process-manager-configuration>
  515. pm.max-children)
  516. (list
  517. "pm = static\n"
  518. "pm.max_children =" (number->string pm.max-children) "\n"))
  519. (($ <php-fpm-on-demand-process-manager-configuration>
  520. pm.max-children
  521. pm.process-idle-timeout)
  522. (list
  523. "pm = ondemand\n"
  524. "pm.max_children =" (number->string pm.max-children) "\n"
  525. "pm.process_idle_timeout =" (number->string pm.process-idle-timeout) "s\n")))
  526. "php_flag[display_errors] = " (if display-errors "on" "off") "\n"
  527. (if workers-log-file
  528. (list "catch_workers_output = yes\n"
  529. "php_admin_value[error_log] =" workers-log-file "\n"
  530. "php_admin_flag[log_errors] = on\n")
  531. (list "catch_workers_output = no\n")))))
  532. (define php-fpm-shepherd-service
  533. (match-lambda
  534. (($ <php-fpm-configuration> php socket user group socket-user socket-group
  535. pid-file log-file pm display-errors workers-log-file file)
  536. (list (shepherd-service
  537. (provision '(php-fpm))
  538. (documentation "Run the php-fpm daemon.")
  539. (requirement '(networking))
  540. (start #~(make-forkexec-constructor
  541. '(#$(file-append php "/sbin/php-fpm")
  542. "--fpm-config"
  543. #$(or file
  544. (default-php-fpm-config socket user group
  545. socket-user socket-group pid-file log-file
  546. pm display-errors workers-log-file)))
  547. #:pid-file #$pid-file))
  548. (stop #~(make-kill-destructor)))))))
  549. (define php-fpm-activation
  550. (match-lambda
  551. (($ <php-fpm-configuration> _ _ user _ _ _ _ log-file _ _ workers-log-file _)
  552. #~(begin
  553. (use-modules (guix build utils))
  554. (let* ((user (getpwnam #$user))
  555. (touch (lambda (file-name)
  556. (call-with-output-file file-name (const #t))))
  557. (init-log-file
  558. (lambda (file-name)
  559. (when #$workers-log-file
  560. (when (not (file-exists? file-name))
  561. (touch file-name))
  562. (chown file-name (passwd:uid user) (passwd:gid user))
  563. (chmod file-name #o660)))))
  564. (init-log-file #$log-file)
  565. (init-log-file #$workers-log-file))))))
  566. (define php-fpm-service-type
  567. (service-type
  568. (name 'php-fpm)
  569. (description
  570. "Run @command{php-fpm} to provide a fastcgi socket for calling php through
  571. a webserver.")
  572. (extensions
  573. (list (service-extension shepherd-root-service-type
  574. php-fpm-shepherd-service)
  575. (service-extension activation-service-type
  576. php-fpm-activation)
  577. (service-extension account-service-type
  578. php-fpm-accounts)))
  579. (default-value (php-fpm-configuration))))
  580. (define* (nginx-php-location
  581. #:key
  582. (nginx-package nginx)
  583. (socket (string-append "/var/run/php"
  584. (version-major (package-version php))
  585. "-fpm.sock")))
  586. "Return a nginx-location-configuration that makes nginx run .php files."
  587. (nginx-location-configuration
  588. (uri "~ \\.php$")
  589. (body (list
  590. "fastcgi_split_path_info ^(.+\\.php)(/.+)$;"
  591. (string-append "fastcgi_pass unix:" socket ";")
  592. "fastcgi_index index.php;"
  593. (list "include " nginx-package "/share/nginx/conf/fastcgi.conf;")))))