diff mbox

improve nginx-service

Message ID 20161016143347.38d8a6f2@polymos.lepiller.eu
State New
Headers show

Commit Message

Julien Lepiller Oct. 16, 2016, 12:33 p.m. UTC
Hi,

this patch fixes a problem with nginx configuration (ensuring some
directories are available to nginx) and adds vhost support in its
configuration. Also updates the doc accordingly.

Comments

Ludovic Courtès Oct. 19, 2016, 9:04 p.m. UTC | #1
Hi Julien,

This looks like a great improvement to me!  Sounds nicer than fiddling
with config files.

I suppose we could make ‘nginx-service-type’ extensible (info "(guix)
Service Types and Services") so that people can write services that
define new vhosts?

Julien Lepiller <julien@lepiller.eu> skribis:

> From 613d5db739d4010be2037fd2fcfc70baca4625aa Mon Sep 17 00:00:00 2001
> From: Julien Lepiller <julien@lepiller.eu>
> Date: Mon, 26 Sep 2016 23:55:58 +0200
> Subject: [PATCH] services: improve nginx-service configuration
>
> * gnu/services/web.scm (<nginx-vhost-configuration>): New record type.
> * doc/guix.texi (Web Services): Document 'nginx-vhost-configuration'.

Please mention the other changes in web.scm: new procedures, changes in
existing procedures, etc.

> +As an alternative to using a @var{config-file}, @var{vhost-list} can be
> +used to specify the list of vhosts required on the host.  For this to work,

“the list of @dfn{virtual hosts} or @dfn{vhosts}”

> +@deftp {Data Type} nginx-vhost-configuration
> +Data type representing the configuration of an nginx virtual host.

@dfn{virtual host}

> +This type has the following parameters:
> +@table @asis
> +@item @code{http-port} (default: 80)

@code{80}; likewise for all the other default values.

> +Nginx will listen for http connection on this port. Set it at #f if nginx should
> +not listen for http (non secure) connection for this vhost.

s/http/HTTP/ and s/#f/@code{#f}/
Please leave two spaces after an end-of-sentence period.

> +(define (list-names names)
> + (match names
> +  ('() "")
> +  ((head tail ...) (string-append (if (eq? head 'default) "_" head)
> +                                  " "
> +                                  (list-names tail)))))

Maybe call it ‘config-value-strings’?  Please add a docstring.  I think
it’d be more readable like this:

  (define (config-value-strings names)
    "Return a string denoting the nginx config representation of NAMES,
   a list of foobars…"
    (string-concatenate
     (map (match-lambda
            ('default "_")
            ((? string? str) str))
          names)))

Could you send an updated patch?

Unless David, who initially wrote this service has objections, this
patch looks good to me with the changes as suggested above.

Thanks!

Ludo’.
diff mbox

Patch

From 613d5db739d4010be2037fd2fcfc70baca4625aa Mon Sep 17 00:00:00 2001
From: Julien Lepiller <julien@lepiller.eu>
Date: Mon, 26 Sep 2016 23:55:58 +0200
Subject: [PATCH] services: improve nginx-service configuration

* gnu/services/web.scm (<nginx-vhost-configuration>): New record type.
* doc/guix.texi (Web Services): Document 'nginx-vhost-configuration'.
---
 doc/guix.texi        | 44 ++++++++++++++++++++++++++++
 gnu/services/web.scm | 81 +++++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 121 insertions(+), 4 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 47fc199..2e7af90 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -10370,6 +10370,7 @@  The @code{(gnu services web)} module provides the following service:
 @deffn {Scheme Procedure} nginx-service [#:nginx nginx] @
        [#:log-directory ``/var/log/nginx''] @
        [#:run-directory ``/var/run/nginx''] @
+       [#:vhost-list (list (nginx-vhost-configuration))] @
        [#:config-file]
 
 Return a service that runs @var{nginx}, the nginx web server.
@@ -10380,8 +10381,51 @@  files are written to @var{run-directory}.  For proper operation, these
 arguments should match what is in @var{config-file} to ensure that the
 directories are created when the service is activated.
 
+As an alternative to using a @var{config-file}, @var{vhost-list} can be
+used to specify the list of vhosts required on the host.  For this to work,
+use the default value for @var{config-file}.
+
 @end deffn
 
+@deftp {Data Type} nginx-vhost-configuration
+Data type representing the configuration of an nginx virtual host.
+This type has the following parameters:
+@table @asis
+@item @code{http-port} (default: 80)
+Nginx will listen for http connection on this port. Set it at #f if nginx should
+not listen for http (non secure) connection for this vhost.
+
+@item @code{https-port} (default: 443)
+Nginx will listen for https connection on this port. Set it at #f if nginx
+should not listen for https (secure) connection for this vhost.
+
+Note that nginx can listen for http and https connections in the same vhost.
+
+@item @code{server-name} (default: @code{(list 'default)})
+A list of server names this vhost represents. @code{'default} represents the
+default vhost for connections matching no other vhost.
+
+@item @code{root} (default: ``/srv/http'')
+Root of the website nginx will serve.
+
+@item @code{index} (default: @code{(list ``index.html'')})
+Index files to look for when clients ask for a directory. If it cannot be found,
+Nginx will send the list of files in the directory.
+
+@item @code{ssl-certificate} (default: ``/etc/nginx/cert.pem'')
+Where to find the certificate for secure connections. Set it to #f if you don't
+have a certificate or you don't want to use https.
+
+@item @code{ssl-certificate-key} (default: ``/etc/nginx/key.pem'')
+Where to find the private key for secure connections. Set it to #f if you don't
+have a key or you don't want to use https.
+
+@item @code{server-tokens?} (default: #f)
+Whether the server should add its configuration to response.
+
+@end table
+@end deftp
+
 @node Network File System
 @subsubsection Network File System
 @cindex NFS
diff --git a/gnu/services/web.scm b/gnu/services/web.scm
index 0a2a09b..dca4972 100644
--- a/gnu/services/web.scm
+++ b/gnu/services/web.scm
@@ -2,6 +2,7 @@ 
 ;;; Copyright © 2015 David Thompson <davet@gnu.org>
 ;;; Copyright © 2015, 2016 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2016 ng0 <ng0@we.make.ritual.n0.is>
+;;; Copyright © 2016 Julien Lepiller <julien@lepiller.eu>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -29,6 +30,8 @@ 
   #:use-module (ice-9 match)
   #:export (nginx-configuration
             nginx-configuration?
+            nginx-vhost-configuration
+            nginx-vhost-configuration?
             nginx-service
             nginx-service-type))
 
@@ -38,6 +41,26 @@ 
 ;;;
 ;;; Code:
 
+(define-record-type* <nginx-vhost-configuration>
+  nginx-vhost-configuration make-nginx-vhost-configuration
+  nginx-vhost-configuration?
+  (http-port           nginx-vhost-configuration-http-port
+                       (default 80))
+  (https-port          nginx-vhost-configuration-https-port
+                       (default 443))
+  (server-name         nginx-vhost-configuration-server-name
+                       (default (list 'default)))
+  (root                nginx-vhost-configuration-root
+                       (default "/srv/http"))
+  (index               nginx-vhost-configuration-index
+                       (default (list "index.html")))
+  (ssl-certificate     nginx-vhost-configuration-ssl-certificate
+                       (default "/etc/nginx/cert.pem"))
+  (ssh-certificate-key nginx-vhost-configuration-ssl-certificate-key
+                       (default "/etc/nginx/key.pem"))
+  (server-tokens?      nginx-vhost-configuration-server-tokens?
+                       (default #f)))
+
 (define-record-type* <nginx-configuration>
   nginx-configuration make-nginx-configuration
   nginx-configuration?
@@ -46,16 +69,59 @@ 
   (run-directory nginx-configuration-run-directory) ;string
   (file          nginx-configuration-file))         ;string | file-like
 
-(define (default-nginx-config log-directory run-directory)
+(define (list-names names)
+ (match names
+  ('() "")
+  ((head tail ...) (string-append (if (eq? head 'default) "_" head)
+                                  " "
+                                  (list-names tail)))))
+
+(define (default-nginx-vhost-config vhost)
+  (string-append 
+   "    server {\n"
+   (if (nginx-vhost-configuration-http-port vhost)
+       (string-append "      listen "
+                      (number->string (nginx-vhost-configuration-http-port vhost))
+                      ";\n")
+       "")
+   (if (nginx-vhost-configuration-https-port vhost)
+       (string-append "      listen "
+                      (number->string (nginx-vhost-configuration-https-port vhost))
+                      " ssl;\n")
+       "")
+   "      server_name " (list-names (nginx-vhost-configuration-server-name vhost))
+                        ";\n"
+   (if (nginx-vhost-configuration-ssl-certificate vhost)
+       (string-append "      ssl_certificate "
+                      (nginx-vhost-configuration-ssl-certificate vhost) ";\n")
+       "")
+   (if (nginx-vhost-configuration-ssl-certificate-key vhost)
+       (string-append "      ssl_certificate_key "
+                      (nginx-vhost-configuration-ssl-certificate-key vhost) ";\n")
+       "")
+   "      root " (nginx-vhost-configuration-root vhost) ";\n"
+   "      index " (list-names (nginx-vhost-configuration-index vhost)) ";\n"
+   "      server_tokens " (if (nginx-vhost-configuration-server-tokens? vhost)
+                              "on" "off") ";\n"
+   "    }\n"))
+
+(define (default-nginx-config log-directory run-directory vhost-list)
   (plain-file "nginx.conf"
               (string-append
                "user nginx nginx;\n"
                "pid " run-directory "/pid;\n"
                "error_log " log-directory "/error.log info;\n"
                "http {\n"
+               "    client_body_temp_path " run-directory "/client_body_temp;\n"
+               "    proxy_temp_path " run-directory "/proxy_temp;\n"
+               "    fastcgi_temp_path " run-directory "/fastcgi_temp;\n"
+               "    uwsgi_temp_path " run-directory "/uwsgi_temp;\n"
+               "    scgi_temp_path " run-directory "/scgi_temp;\n"
                "    access_log " log-directory "/access.log;\n"
-               "    root /var/www;\n"
-               "    server {}\n"
+               (let ((http (map default-nginx-vhost-config vhost-list)))
+                    (do ((http http (cdr http)) 
+                         (block "" (string-append (car http) "\n" block )))
+                        ((null? http) block)))
                "}\n"
                "events {}\n")))
 
@@ -79,6 +145,12 @@ 
          (mkdir-p #$log-directory)
          (format #t "creating nginx run directory '~a'~%" #$run-directory)
          (mkdir-p #$run-directory)
+         (format #t "creating nginx temp directories '~a/{client_body,proxy,fastcgi,uwsgi,scgi}_temp'~%" #$run-directory)
+         (mkdir-p (string-append #$run-directory "/client_body_temp"))
+         (mkdir-p (string-append #$run-directory "/proxy_temp"))
+         (mkdir-p (string-append #$run-directory "/fastcgi_temp"))
+         (mkdir-p (string-append #$run-directory "/uwsgi_temp"))
+         (mkdir-p (string-append #$run-directory "/scgi_temp"))
          ;; Check configuration file syntax.
          (system* (string-append #$nginx "/sbin/nginx")
                   "-c" #$config-file "-t")))))
@@ -114,8 +186,9 @@ 
 (define* (nginx-service #:key (nginx nginx)
                         (log-directory "/var/log/nginx")
                         (run-directory "/var/run/nginx")
+                        (vhost-list (list (nginx-vhost-configuration)))
                         (config-file
-                         (default-nginx-config log-directory run-directory)))
+                         (default-nginx-config log-directory run-directory vhost-list)))
   "Return a service that runs NGINX, the nginx web server.
 
 The nginx daemon loads its runtime configuration from CONFIG-FILE, stores log
-- 
2.10.1