Commit | Line | Data |
---|---|---|
58724c48 DT |
1 | ;;; GNU Guix --- Functional package management for GNU |
2 | ;;; Copyright © 2015 David Thompson <davet@gnu.org> | |
24e96431 | 3 | ;;; Copyright © 2015, 2016 Ludovic Courtès <ludo@gnu.org> |
6c12abbd | 4 | ;;; Copyright © 2016 ng0 <ng0@we.make.ritual.n0.is> |
8c00b838 | 5 | ;;; Copyright © 2016 Julien Lepiller <julien@lepiller.eu> |
58724c48 DT |
6 | ;;; |
7 | ;;; This file is part of GNU Guix. | |
8 | ;;; | |
9 | ;;; GNU Guix is free software; you can redistribute it and/or modify it | |
10 | ;;; under the terms of the GNU General Public License as published by | |
11 | ;;; the Free Software Foundation; either version 3 of the License, or (at | |
12 | ;;; your option) any later version. | |
13 | ;;; | |
14 | ;;; GNU Guix is distributed in the hope that it will be useful, but | |
15 | ;;; WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | ;;; GNU General Public License for more details. | |
18 | ;;; | |
19 | ;;; You should have received a copy of the GNU General Public License | |
20 | ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. | |
21 | ||
22 | (define-module (gnu services web) | |
23 | #:use-module (gnu services) | |
0190c1c0 | 24 | #:use-module (gnu services shepherd) |
58724c48 DT |
25 | #:use-module (gnu system shadow) |
26 | #:use-module (gnu packages admin) | |
27 | #:use-module (gnu packages web) | |
28 | #:use-module (guix records) | |
58724c48 | 29 | #:use-module (guix gexp) |
0adfe95a | 30 | #:use-module (ice-9 match) |
24e96431 TČ |
31 | #:export (nginx-configuration |
32 | nginx-configuration? | |
8c00b838 JL |
33 | nginx-vhost-configuration |
34 | nginx-vhost-configuration? | |
24e96431 TČ |
35 | nginx-service |
36 | nginx-service-type)) | |
58724c48 DT |
37 | |
38 | ;;; Commentary: | |
39 | ;;; | |
40 | ;;; Web services. | |
41 | ;;; | |
42 | ;;; Code: | |
43 | ||
8c00b838 JL |
44 | (define-record-type* <nginx-vhost-configuration> |
45 | nginx-vhost-configuration make-nginx-vhost-configuration | |
46 | nginx-vhost-configuration? | |
47 | (http-port nginx-vhost-configuration-http-port | |
48 | (default 80)) | |
49 | (https-port nginx-vhost-configuration-https-port | |
50 | (default 443)) | |
51 | (server-name nginx-vhost-configuration-server-name | |
52 | (default (list 'default))) | |
53 | (root nginx-vhost-configuration-root | |
54 | (default "/srv/http")) | |
55 | (index nginx-vhost-configuration-index | |
56 | (default (list "index.html"))) | |
57 | (ssl-certificate nginx-vhost-configuration-ssl-certificate | |
58 | (default "/etc/nginx/cert.pem")) | |
59 | (ssl-certificate-key nginx-vhost-configuration-ssl-certificate-key | |
60 | (default "/etc/nginx/key.pem")) | |
61 | (server-tokens? nginx-vhost-configuration-server-tokens? | |
62 | (default #f))) | |
63 | ||
0adfe95a LC |
64 | (define-record-type* <nginx-configuration> |
65 | nginx-configuration make-nginx-configuration | |
66 | nginx-configuration? | |
67 | (nginx nginx-configuration-nginx) ;<package> | |
68 | (log-directory nginx-configuration-log-directory) ;string | |
69 | (run-directory nginx-configuration-run-directory) ;string | |
70 | (file nginx-configuration-file)) ;string | file-like | |
71 | ||
8c00b838 JL |
72 | (define (config-domain-strings names) |
73 | "Return a string denoting the nginx config representation of NAMES, a list | |
74 | of domain names." | |
75 | (string-concatenate | |
76 | (map (match-lambda | |
77 | ('default "_") | |
78 | ((? string? str) str)) | |
79 | names))) | |
80 | ||
81 | (define (config-index-strings names) | |
82 | "Return a string denoting the nginx config representation of NAMES, a list | |
83 | of index files." | |
84 | (string-concatenate | |
85 | (map (match-lambda | |
86 | ((? string? str) str)) | |
87 | names))) | |
88 | ||
89 | (define (default-nginx-vhost-config vhost) | |
90 | (string-append | |
91 | " server {\n" | |
92 | (if (nginx-vhost-configuration-http-port vhost) | |
93 | (string-append " listen " | |
94 | (number->string (nginx-vhost-configuration-http-port vhost)) | |
95 | ";\n") | |
96 | "") | |
97 | (if (nginx-vhost-configuration-https-port vhost) | |
98 | (string-append " listen " | |
99 | (number->string (nginx-vhost-configuration-https-port vhost)) | |
100 | " ssl;\n") | |
101 | "") | |
102 | " server_name " (config-domain-strings | |
103 | (nginx-vhost-configuration-server-name vhost)) | |
104 | ";\n" | |
105 | (if (nginx-vhost-configuration-ssl-certificate vhost) | |
106 | (string-append " ssl_certificate " | |
107 | (nginx-vhost-configuration-ssl-certificate vhost) ";\n") | |
108 | "") | |
109 | (if (nginx-vhost-configuration-ssl-certificate-key vhost) | |
110 | (string-append " ssl_certificate_key " | |
111 | (nginx-vhost-configuration-ssl-certificate-key vhost) ";\n") | |
112 | "") | |
113 | " root " (nginx-vhost-configuration-root vhost) ";\n" | |
114 | " index " (config-index-strings (nginx-vhost-configuration-index vhost)) ";\n" | |
115 | " server_tokens " (if (nginx-vhost-configuration-server-tokens? vhost) | |
116 | "on" "off") ";\n" | |
117 | " }\n")) | |
118 | ||
119 | (define (default-nginx-config log-directory run-directory vhost-list) | |
58724c48 DT |
120 | (plain-file "nginx.conf" |
121 | (string-append | |
122 | "user nginx nginx;\n" | |
123 | "pid " run-directory "/pid;\n" | |
124 | "error_log " log-directory "/error.log info;\n" | |
125 | "http {\n" | |
8c00b838 JL |
126 | " client_body_temp_path " run-directory "/client_body_temp;\n" |
127 | " proxy_temp_path " run-directory "/proxy_temp;\n" | |
128 | " fastcgi_temp_path " run-directory "/fastcgi_temp;\n" | |
129 | " uwsgi_temp_path " run-directory "/uwsgi_temp;\n" | |
130 | " scgi_temp_path " run-directory "/scgi_temp;\n" | |
58724c48 | 131 | " access_log " log-directory "/access.log;\n" |
8c00b838 JL |
132 | (let ((http (map default-nginx-vhost-config vhost-list))) |
133 | (do ((http http (cdr http)) | |
134 | (block "" (string-append (car http) "\n" block ))) | |
135 | ((null? http) block))) | |
58724c48 DT |
136 | "}\n" |
137 | "events {}\n"))) | |
138 | ||
0adfe95a LC |
139 | (define %nginx-accounts |
140 | (list (user-group (name "nginx") (system? #t)) | |
141 | (user-account | |
142 | (name "nginx") | |
143 | (group "nginx") | |
144 | (system? #t) | |
145 | (comment "nginx server user") | |
146 | (home-directory "/var/empty") | |
9e41130b | 147 | (shell (file-append shadow "/sbin/nologin"))))) |
0adfe95a LC |
148 | |
149 | (define nginx-activation | |
150 | (match-lambda | |
151 | (($ <nginx-configuration> nginx log-directory run-directory config-file) | |
152 | #~(begin | |
153 | (use-modules (guix build utils)) | |
154 | ||
155 | (format #t "creating nginx log directory '~a'~%" #$log-directory) | |
156 | (mkdir-p #$log-directory) | |
157 | (format #t "creating nginx run directory '~a'~%" #$run-directory) | |
158 | (mkdir-p #$run-directory) | |
8c00b838 JL |
159 | (format #t "creating nginx temp directories '~a/{client_body,proxy,fastcgi,uwsgi,scgi}_temp'~%" #$run-directory) |
160 | (mkdir-p (string-append #$run-directory "/client_body_temp")) | |
161 | (mkdir-p (string-append #$run-directory "/proxy_temp")) | |
162 | (mkdir-p (string-append #$run-directory "/fastcgi_temp")) | |
163 | (mkdir-p (string-append #$run-directory "/uwsgi_temp")) | |
164 | (mkdir-p (string-append #$run-directory "/scgi_temp")) | |
0adfe95a | 165 | ;; Check configuration file syntax. |
d21047d5 | 166 | (system* (string-append #$nginx "/sbin/nginx") |
0adfe95a LC |
167 | "-c" #$config-file "-t"))))) |
168 | ||
d4053c71 | 169 | (define nginx-shepherd-service |
0adfe95a LC |
170 | (match-lambda |
171 | (($ <nginx-configuration> nginx log-directory run-directory config-file) | |
9e41130b | 172 | (let* ((nginx-binary (file-append nginx "/sbin/nginx")) |
0adfe95a LC |
173 | (nginx-action |
174 | (lambda args | |
175 | #~(lambda _ | |
176 | (zero? | |
177 | (system* #$nginx-binary "-c" #$config-file #$@args)))))) | |
178 | ||
179 | ;; TODO: Add 'reload' action. | |
d4053c71 | 180 | (list (shepherd-service |
0adfe95a LC |
181 | (provision '(nginx)) |
182 | (documentation "Run the nginx daemon.") | |
183 | (requirement '(user-processes loopback)) | |
184 | (start (nginx-action "-p" run-directory)) | |
185 | (stop (nginx-action "-s" "stop")))))))) | |
186 | ||
187 | (define nginx-service-type | |
188 | (service-type (name 'nginx) | |
189 | (extensions | |
d4053c71 AK |
190 | (list (service-extension shepherd-root-service-type |
191 | nginx-shepherd-service) | |
0adfe95a LC |
192 | (service-extension activation-service-type |
193 | nginx-activation) | |
194 | (service-extension account-service-type | |
195 | (const %nginx-accounts)))))) | |
196 | ||
58724c48 DT |
197 | (define* (nginx-service #:key (nginx nginx) |
198 | (log-directory "/var/log/nginx") | |
199 | (run-directory "/var/run/nginx") | |
8c00b838 | 200 | (vhost-list (list (nginx-vhost-configuration))) |
58724c48 | 201 | (config-file |
8c00b838 | 202 | (default-nginx-config log-directory run-directory vhost-list))) |
58724c48 DT |
203 | "Return a service that runs NGINX, the nginx web server. |
204 | ||
6c12abbd | 205 | The nginx daemon loads its runtime configuration from CONFIG-FILE, stores log |
58724c48 | 206 | files in LOG-DIRECTORY, and stores temporary runtime files in RUN-DIRECTORY." |
0adfe95a LC |
207 | (service nginx-service-type |
208 | (nginx-configuration | |
209 | (nginx nginx) | |
210 | (log-directory log-directory) | |
211 | (run-directory run-directory) | |
212 | (file config-file)))) |