guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

03/06: hydra: Add (sysadmin nginx) module.


From: Ludovic Courtès
Subject: 03/06: hydra: Add (sysadmin nginx) module.
Date: Wed, 22 Dec 2021 06:50:12 -0500 (EST)

civodul pushed a commit to branch master
in repository maintenance.

commit 4cf3743e0daddac99ff71a151a5fd37cbe874493
Author: Ludovic Courtès <ludo@gnu.org>
AuthorDate: Tue Dec 21 23:34:35 2021 +0100

    hydra: Add (sysadmin nginx) module.
    
    This factorizes the guix.gnu.org web site configuration.
    The nginx.conf derivation for berlin.scm is left unchanged.
    
    * hydra/nginx/berlin.scm (le, redirect, %tls-settings)
    (guix.gnu.org-redirect-locations, languages-to-accept)
    (guix.gnu.org-redirects-for-each-language)
    (guix.gnu.org-other-locations, accept-languages): Move to...
    * hydra/modules/sysadmin/nginx.scm: ... here.
    * hydra/nginx/berlin.scm (%berlin-servers): Use
    GUIX.GNU.ORG-NGINX-SERVER instead of the inline copy.
---
 .../berlin.scm => modules/sysadmin/nginx.scm}      | 615 ++----------------
 hydra/nginx/berlin.scm                             | 702 +--------------------
 2 files changed, 70 insertions(+), 1247 deletions(-)

diff --git a/hydra/nginx/berlin.scm b/hydra/modules/sysadmin/nginx.scm
similarity index 75%
copy from hydra/nginx/berlin.scm
copy to hydra/modules/sysadmin/nginx.scm
index 37621d6..81607d6 100644
--- a/hydra/nginx/berlin.scm
+++ b/hydra/modules/sysadmin/nginx.scm
@@ -7,146 +7,19 @@
 ;; Copyright © 2021 Mathieu Othacehe <othacehe@gnu.org>
 ;; Released under the GNU GPLv3 or any later version.
 
-(use-modules (gnu services web)
-             (gnu services version-control)
-             (gnu packages monitoring))
-
+(define-module (sysadmin nginx)
+  #:use-module (gnu services web)
+  #:use-module (gnu services version-control)
+  #:use-module (srfi srfi-1)
+  #:export (%tls-settings
+            le
+            accept-languages
+            guix.gnu.org-nginx-server))
 
 
-(define* (le host #:optional privkey)
-  (string-append "/etc/letsencrypt/live/"
-                 host "/"
-                 (if privkey "privkey" "fullchain")
-                 ".pem"))
-
-(define (redirect old new)
-  (nginx-location-configuration
-   (uri (string-append "= " old)) ;= means highest priority
-   (body (list (string-append "return 301 " new ";\n")))))
-
-(define publish-robots.txt
-  ;; Try to prevent good-faith crawlers from downloading substitutes.  Allow
-  ;; indexing the root—which is expected to be static or cheap—to remain 
visible
-  ;; in search engine results for, e.g., ‘Guix CI’.
-  "\
-User-agent: *\r
-Disallow: /\r
-Allow: /$\r
-\r
-")
-
-(define (publish-locations url)
-  "Return the nginx location blocks for 'guix publish' running on URL."
-  (list (nginx-location-configuration
-         (uri "/nix-cache-info")
-         (body
-          (list
-           (string-append
-            "proxy_pass " url "/nix-cache-info;")
-           ;; Cache this file since that's always the first thing we ask
-           ;; for.
-           "proxy_cache static;"
-           "proxy_cache_valid 200 100d;"     ; cache hits for a looong time.
-           "proxy_cache_valid any 5m;"       ; cache misses/others for 5 min.
-           "proxy_ignore_client_abort on;"
-
-           ;; We need to hide and ignore the Set-Cookie header to enable
-           ;; caching.
-           "proxy_hide_header    Set-Cookie;"
-           "proxy_ignore_headers Set-Cookie;")))
-
-        (nginx-location-configuration
-         (uri "/nar/")
-         (body
-          (list
-           (string-append "proxy_pass " url ";")
-           "client_body_buffer_size 256k;"
-
-           ;; Be more tolerant of delays when fetching a nar.
-           "proxy_read_timeout 60s;"
-           "proxy_send_timeout 60s;"
-
-           ;; Enable caching for nar files, to avoid reconstructing and
-           ;; recompressing archives.
-           "proxy_cache nar;"
-           "proxy_cache_valid 200 30d;"           ; cache hits for 1 month
-           "proxy_cache_valid 504 3m;" ; timeout, when hydra.gnu.org is 
overloaded
-           "proxy_cache_valid any 1h;" ; cache misses/others for 1h.
-
-           "proxy_ignore_client_abort on;"
-
-           ;; Nars are already compressed.
-           "gzip off;"
-
-           ;; We need to hide and ignore the Set-Cookie header to enable
-           ;; caching.
-           "proxy_hide_header    Set-Cookie;"
-           "proxy_ignore_headers Set-Cookie;"
-
-           ;; Provide a 'content-length' header so that 'guix
-           ;; substitute-binary' knows upfront how much it is downloading.
-           ;; "add_header Content-Length $body_bytes_sent;"
-           )))
-
-        (nginx-location-configuration
-         (uri "~ \\.narinfo$")
-         (body
-          (list
-           ;; Since 'guix publish' has its own caching, and since it relies
-           ;; on the atime of cached narinfos to determine whether a
-           ;; narinfo can be removed from the cache, don't do any caching
-           ;; here.
-           (string-append "proxy_pass " url ";")
-
-           ;; For HTTP pipelining.  This has a dramatic impact on
-           ;; performance.
-           "client_body_buffer_size 128k;"
-
-           ;; Narinfos requests are short, serve many of them on a
-           ;; connection.
-           "keepalive_requests 600;"
-
-           ;; Do not tolerate slowness of hydra.gnu.org when fetching
-           ;; narinfos: better return 504 quickly than wait forever.
-           "proxy_connect_timeout 10s;"
-           "proxy_read_timeout 10s;"
-           "proxy_send_timeout 10s;"
-
-           ;; 'guix publish --ttl' produces a 'Cache-Control' header for
-           ;; use by 'guix substitute'.  Let it through rather than use
-           ;; nginx's "expire" directive since the expiration time defined
-           ;; by 'guix publish' is the right one.
-           "proxy_pass_header Cache-Control;"
-
-           "proxy_ignore_client_abort on;"
-
-           ;; We need to hide and ignore the Set-Cookie header to enable
-           ;; caching.
-           "proxy_hide_header    Set-Cookie;"
-           "proxy_ignore_headers Set-Cookie;")))
-
-        ;; Content-addressed files served by 'guix publish'.
-        (nginx-location-configuration
-         (uri "/file/")
-         (body
-          (list
-           (string-append "proxy_pass " url ";")
-
-           "proxy_cache cas;"
-           "proxy_cache_valid 200 200d;"          ; cache hits
-           "proxy_cache_valid any 5m;"            ; cache misses/others
-
-           "proxy_ignore_client_abort on;")))
-
-       ;; Try to prevent good-faith crawlers from downloading substitutes.
-       (nginx-location-configuration
-        (uri "= /robots.txt")
-        (body
-         (list
-          #~(string-append "try_files "
-                           #$(plain-file "robots.txt" publish-robots.txt)
-                           " =404;")
-          "root /;")))))
+;;;
+;;; Tools.
+;;;
 
 (define %tls-settings
   (list
@@ -161,41 +34,44 @@ Allow: /$\r
    ;; as suggested at <https://weakdh.org/sysadmin.html>.
    "ssl_dhparam         /etc/dhparams.pem;"))
 
-(define (berlin-locations publish-url)
-  "Return nginx location blocks with 'guix publish' reachable at
-PUBLISH-URL."
-  (append (publish-locations publish-url)
-          (list
-           ;; Cuirass.
-           (nginx-location-configuration
-            (uri "/")
-            (body (list "proxy_pass http://localhost:8081;";)))
-           (nginx-location-configuration
-            (uri "~ ^/admin")
-            (body
-             (list "if ($ssl_client_verify != SUCCESS) { return 403; } 
proxy_pass http://localhost:8081;";)))
+(define* (le host #:optional privkey)
+  (string-append "/etc/letsencrypt/live/"
+                 host "/"
+                 (if privkey "privkey" "fullchain")
+                 ".pem"))
 
-           (nginx-location-configuration
-            (uri "/static")
-            (body
-             (list
-              "proxy_pass http://localhost:8081;";
-              ;; Let browsers cache this for a while.
-              "expires 10d;"
-              ;; Cache quite aggressively.
-              "proxy_cache static;"
-              "proxy_cache_valid 200 5d;"
-              "proxy_cache_valid any 10m;"
-              "proxy_ignore_client_abort on;")))
+(define* (accept-languages
+          #:optional (language-lists
+                      languages-to-accept))
+  "Returns nginx configuration code to set up the $lang variable
+according to the Accept-Language header in the HTTP request.  The
+requesting user agent will be served the files at /$lang/some/url.
+Each list in LANGUAGE-LISTS starts with the $lang and is followed by
+synonymous IETF language tags that should be mapped to the same $lang."
+  (define (language-mappings language-list)
+    (define (language-mapping language)
+      (string-join (list "    "  language (car language-list) ";")))
+    (string-join (map language-mapping language-list) "\n"))
 
-           (nginx-location-configuration          ;certbot
-            (uri "/.well-known")
-            (body (list "root /var/www;")))
+  (let ((directives
+         `(,(string-join
+             `("set_from_accept_language $lang_unmapped"
+               ,@(map string-join language-lists)
+               ";"))
+           "map $lang_unmapped $lang {"
+           ,@(map language-mappings language-lists)
+           "}")))
+    (string-join directives "\n")))
 
-           (nginx-location-configuration
-            (uri "/berlin.guixsd.org-export.pub")
-            (body
-             (list "root /var/www/guix;"))))))
+(define (redirect old new)
+  (nginx-location-configuration
+   (uri (string-append "= " old)) ;= means highest priority
+   (body (list (string-append "return 301 " new ";\n")))))
+
+
+;;;
+;;; The guix.gnu.org web site.
+;;;
 
 (define guix.gnu.org-redirect-locations
   (list
@@ -808,7 +684,7 @@ PUBLISH-URL."
    (git-http-nginx-location-configuration
     (git-http-configuration))
 
-   ;; For Hurd bootstrap binaries.
+   ;; XXX: For Hurd bootstrap binaries.
    (nginx-location-configuration
     (uri "/guix")
     (body (list "root /var/www;")))
@@ -826,385 +702,26 @@ PUBLISH-URL."
           (guix.gnu.org-redirects-for-each-language)
           guix.gnu.org-other-locations))
 
-(define %publish-url "http://localhost:3000";)
-
-(define %berlin-servers
-  (list
-   ;; Redirect domains that don't explicitly support HTTP (below) to HTTPS.
-   (nginx-server-configuration
-    (listen '("80"))
-    (raw-content
-     (list "return 308 https://$host$request_uri;";)))
-
-   ;; Domains that still explicitly support plain HTTP.
-   (nginx-server-configuration
-    (listen '("80"))
-    (server-name '("ci.guix.gnu.org"
-                  ;; <https://logs.guix.gnu.org/guix/2021-11-20.log#155427>
-                  "~[0-9]$"))
-    (locations (berlin-locations %publish-url))
-    (raw-content
-     (list
-      "access_log  /var/log/nginx/http.access.log;"
-      "proxy_set_header X-Forwarded-Host $host;"
-      "proxy_set_header X-Forwarded-Port $server_port;"
-      "proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;")))
-
-   (nginx-server-configuration
-    (listen '("80"))
-    (server-name '("bootstrappable.org"
-                   "www.bootstrappable.org"))
-    (root "/srv/bootstrappable.org")
-    (raw-content
-     (list
-      "access_log /var/log/nginx/bootstrappable.access.log;")))
-
-   (nginx-server-configuration
-    (listen '("80"))
-    (server-name '("disarchive.guix.gnu.org"))
-    (root "/gnu/disarchive")
-    (raw-content
-     ;; Tell nginx to always read 'FILE.gz' when asked for 'FILE', and to
-     ;; gunzip it on the fly (because the client for this typically doesn't
-     ;; properly support gzip encoding).
-     (list "gzip_static always; gunzip on;\n"
-           "access_log /var/log/nginx/disarchive.access.log;")))
-
-   (nginx-server-configuration
-    (listen '("80"))
-    (server-name '("guixwl.org"
-                   "www.guixwl.org"))
-    (root "/home/rekado/gwl/")
-    (locations
-     (list (nginx-location-configuration ;certbot
-            (uri "/.well-known")
-            (body (list "root /var/www;")))
-
-           (nginx-location-configuration
-            (uri "/manual")
-            (body (list "alias /srv/gwl-manual;")))
-
-           ;; Pass requests to 'guix workflow --web-interface'.
-           (nginx-location-configuration
-            (uri "/")
-            (body '("proxy_pass http://localhost:5000;";)))))
-    (raw-content
-     (list
-      "access_log /var/log/nginx/workflows-guix-info.access.log;")))
-        
-   ;; HTTPS servers
-   (nginx-server-configuration
-    (listen '("443 ssl"))
-    (server-name '("ci.guix.gnu.org"))
-    (ssl-certificate (le "ci.guix.gnu.org"))
-    (ssl-certificate-key (le "ci.guix.gnu.org" 'key))
-    (locations (berlin-locations %publish-url))
-    (raw-content
-     (append
-      %tls-settings
-      (list
-       "access_log  /var/log/nginx/https.access.log;"
-       "proxy_set_header X-Forwarded-Host $host;"
-       "proxy_set_header X-Forwarded-Port $server_port;"
-       "proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;"
-       ;; For Cuirass admin interface authentication
-       "ssl_client_certificate /etc/ssl-ca/certs/ca.crt;"
-       "ssl_crl /etc/ssl-ca/private/ca.crl;"
-       "ssl_verify_client optional;"))))
-
-   (nginx-server-configuration
-    (listen '("443 ssl"))
-    (server-name '("qualif.ci.guix.gnu.org"))
-    (locations (berlin-locations "http://localhost:3003";))
-    (raw-content
-     (append %tls-settings
-             '("access_log  /var/log/nginx/qualif.access.log;"))))
-
-   (nginx-server-configuration
-    (listen '("443 ssl"))
-    (server-name '("bootstrappable.org"
-                   "www.bootstrappable.org"))
-    (ssl-certificate (le "bootstrappable.org"))
-    (ssl-certificate-key (le "bootstrappable.org" 'key))
-    (root "/srv/bootstrappable.org")
-    (locations
-     (list (nginx-location-configuration ;certbot
-            (uri "/.well-known")
-            (body (list "root /var/www;")))))
-    (raw-content
-     (append
-      %tls-settings
-      (list
-       "access_log /var/log/nginx/bootstrappable.https.access.log;"))))
-
-   (nginx-server-configuration
-    (listen '("443 ssl"))
-    (server-name '("disarchive.guix.gnu.org"))
-    (ssl-certificate (le "disarchive.guix.gnu.org"))
-    (ssl-certificate-key (le "disarchive.guix.gnu.org" 'key))
-    (root "/gnu/disarchive")
-    (raw-content
-     (list "gzip_static always; gunzip on;\n"
-           "access_log /var/log/nginx/disarchive.access.log;")))
-
-   (nginx-server-configuration
-    (listen '("443 ssl"))
-    (server-name '("guix.gnu.org"))
-    (ssl-certificate (le "guix.gnu.org"))
-    (ssl-certificate-key (le "guix.gnu.org" 'key))
-    (root "/srv/guix.gnu.org")
-    (locations guix.gnu.org-locations)
-    (raw-content
-     (append
-      %tls-settings
-      (list
-       "add_header Content-Security-Policy \"frame-ancestors 'none'\";"
-
-       ;; TODO This works around NGinx using the epoch for the
-       ;; Last-Modified date, as well as the etag.
-       ;; See http://issues.guix.gnu.org/37207
-       "add_header Last-Modified \"\";"
-       "if_modified_since off;"
-       "etag off;"
-
-       "rewrite (.*)/$ $1/index.html;"
-       "access_log /var/log/nginx/guix-gnu-org.https.access.log;"))))
-
-   (nginx-server-configuration
-    (listen '("443 ssl"))
-    (server-name '("issues.guix.gnu.org"))
-    (ssl-certificate (le "issues.guix.gnu.org"))
-    (ssl-certificate-key (le "issues.guix.gnu.org" 'key))
-    (root "/home/rekado/mumi/")
-    (locations
-     (list (nginx-location-configuration
-            (uri "/")
-            (body '("proxy_pass http://localhost:1234;";)))))
-    (raw-content
-     (append
-      %tls-settings
-      (list
-       "proxy_set_header X-Forwarded-Host $host;"
-       "proxy_set_header X-Forwarded-Port $server_port;"
-       "proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;"
-       "proxy_connect_timeout       600;"
-       "proxy_send_timeout          600;"
-       "proxy_read_timeout          600;"
-       "send_timeout                600;"
-       "access_log /var/log/nginx/issues-guix-gnu-org.https.access.log;"))))
-
-   (nginx-server-configuration
-    (listen '("443 ssl"))
-    (server-name '("guixwl.org"
-                   "www.guixwl.org"))
-    (ssl-certificate (le "www.guixwl.org"))
-    (ssl-certificate-key (le "www.guixwl.org" 'key))
-    (root "/home/rekado/gwl/")
-    (locations
-     (list
-      (nginx-location-configuration
-       (uri "/manual")
-       (body (list "alias /srv/gwl-manual;")))
-      (nginx-location-configuration
-       (uri "/")
-       (body '("proxy_pass http://localhost:5000;";)))))
-    (raw-content
-     (append
-      %tls-settings
-      (list
-       "proxy_set_header X-Forwarded-Host $host;"
-       "proxy_set_header X-Forwarded-Port $server_port;"
-       "proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;"
-       "proxy_connect_timeout       600;"
-       "proxy_send_timeout          600;"
-       "proxy_read_timeout          600;"
-       "send_timeout                600;"
-       "access_log /var/log/nginx/workflows-guix-info.https.access.log;"))))
-
-   ;; Backwards compatibility with legacy hostnames.
-   (nginx-server-configuration
-    (listen '("443 ssl"
-             "80"))
-    (ssl-certificate (le "berlin.guixsd.org"))
-    (ssl-certificate-key (le "berlin.guixsd.org" 'key))
-    (server-name '("berlin.guixsd.org"
-                  "berlin.guix.info"
-                   "ci.guix.info"))
-    (locations
-     (list
-      (nginx-location-configuration
-       (uri "~ /(.*)")
-       (body (list "return 301 $scheme://ci.guix.gnu.org/$1;"))))))
-
-   (nginx-server-configuration
-    (listen '("443 ssl"
-             "80"))
-    (server-name '("guix.info"
-                   "www.guix.info"))
-    (ssl-certificate (le "guix.info"))
-    (ssl-certificate-key (le "guix.info" 'key))
-    (locations
-     (list
-      (nginx-location-configuration
-       (uri "~ /(.*)")
-       (body (list "return 301 $scheme://guix.gnu.org/$1;"))))))
-
-   (nginx-server-configuration
-    (listen '("443 ssl"
-             "80"))
-    (server-name '("issues.guix.info"))
-    (ssl-certificate (le "issues.guix.info"))
-    (ssl-certificate-key (le "issues.guix.info" 'key))
-    (locations
-     (list
-      (nginx-location-configuration
-       (uri "~ /(.*)")
-       (body (list "return 301 $scheme://issues.guix.gnu.org/$1;"))))))
-
-   (nginx-server-configuration
-    (listen '("443 ssl"
-             "80"))
-    (server-name '("workflows.guix.info"
-                   "workflow.guix.info"))
-    (ssl-certificate (le "www.guixwl.org"))
-    (ssl-certificate-key (le "www.guixwl.org" 'key))
-    (locations
-     (list
-      (nginx-location-configuration
-       (uri "~ /(.*)")
-       (body (list "return 301 $scheme://guixwl.org/$1;"))))))))
-
-(define (accept-languages language-lists)
-  "Returns nginx configuration code to set up the $lang variable
-according to the Accept-Language header in the HTTP request.  The
-requesting user agent will be served the files at /$lang/some/url.
-Each list in LANGUAGE-LISTS starts with the $lang and is followed by
-synonymous IETF language tags that should be mapped to the same $lang."
-  (define (language-mappings language-list)
-    (define (language-mapping language)
-      (string-join (list "    "  language (car language-list) ";")))
-    (string-join (map language-mapping language-list) "\n"))
-
-  (let ((directives
-         `(,(string-join
-             `("set_from_accept_language $lang_unmapped"
-               ,@(map string-join language-lists)
-               ";"))
-           "map $lang_unmapped $lang {"
-           ,@(map language-mappings language-lists)
-           "}")))
-    (string-join directives "\n")))
-
-(define %extra-content
-  (list
-   "default_type  application/octet-stream;"
-   "sendfile        on;"
-
-   (accept-languages languages-to-accept)
-
-   ;; Maximum chunk size to send.  Partly this is a workaround for
-   ;; <http://bugs.gnu.org/19939>, but also the nginx docs mention that
-   ;; "Without the limit, one fast connection may seize the worker
-   ;; process entirely."
-   ;;  <http://nginx.org/en/docs/http/ngx_http_core_module#sendfile_max_chunk>
-   "sendfile_max_chunk 1m;"
-
-   "keepalive_timeout  65;"
-
-   ;; Use HTTP 1.1 to talk to the backend so we benefit from keep-alive
-   ;; connections and chunked transfer encoding.  The latter allows us to
-   ;; make sure we do not cache partial downloads.
-   "proxy_http_version 1.1;"
-
-   ;; The 'inactive' parameter for caching is not very useful in our
-   ;; case: all that matters is that LRU sweeping happens when 'max_size'
-   ;; is hit.
-
-   ;; cache for nar files
-   "proxy_cache_path /var/cache/nginx/nar"
-   "     levels=2"
-   "     inactive=8d"      ; inactive keys removed after 8d
-   "     keys_zone=nar:4m"  ; nar cache meta data: ~32K keys
-   "     max_size=10g;"     ; total cache data size max
-
-   ;; cache for content-addressed files
-   "proxy_cache_path /var/cache/nginx/cas"
-   "     levels=2"
-   "     inactive=180d"            ; inactive keys removed after 180d
-   "     keys_zone=cas:8m"  ; nar cache meta data: ~64K keys
-   "     max_size=50g;"         ; total cache data size max
-
-   ;; cache for build logs
-   "proxy_cache_path /var/cache/nginx/logs"
-   "     levels=2"
-   "     inactive=60d"          ; inactive keys removed after 60d
-   "     keys_zone=logs:8m"     ; narinfo meta data: ~64K keys
-   "     max_size=4g;"          ; total cache data size max
-
-   ;; cache for static data
-   "proxy_cache_path /var/cache/nginx/static"
-   "     levels=1"
-   "     inactive=10d"        ; inactive keys removed after 10d
-   "     keys_zone=static:1m"   ; nar cache meta data: ~8K keys
-   "     max_size=200m;"        ; total cache data size max
-
-   ;; If Hydra cannot honor these delays, then something is wrong and
-   ;; we'd better drop the connection and return 504.
-   "proxy_connect_timeout 10s;"
-   "proxy_read_timeout 10s;"
-   "proxy_send_timeout 10s;"
-
-   ;; Cache timeouts for a little while to avoid increasing pressure.
-   "proxy_cache_valid 504 30s;"))
-
-(define %nginx-configuration
-  (nginx-configuration
-   (server-blocks %berlin-servers)
-   (modules
-    (list
-     ;; Module to redirect users to the localized pages of their choice.
-     (file-append nginx-accept-language-module
-                  "/etc/nginx/modules/ngx_http_accept_language_module.so")))
-   (global-directives
-    ;; This is a 72-core machine, but let's not use all of them for nginx.
-    '((worker_processes . 16)
-      (pcre_jit . on)
-      (events . ((worker_connections . 1024)))))
-   (extra-content
-    (string-join %extra-content "\n"))))
-
-(define %zabbix-nginx-server
+(define guix.gnu.org-nginx-server
   (nginx-server-configuration
-   (root #~(string-append #$zabbix-server:front-end "/share/zabbix/php"))
    (listen '("443 ssl"))
-   (server-name '("monitor.guix.gnu.org"))
-   (ssl-certificate (le "monitor.guix.gnu.org"))
-   (ssl-certificate-key (le "monitor.guix.gnu.org" 'key))
-   (index '("index.php"))
+   (server-name '("guix.gnu.org"))
+   (ssl-certificate (le "guix.gnu.org"))
+   (ssl-certificate-key (le "guix.gnu.org" 'key))
+   (root "/srv/guix.gnu.org")
+   (locations guix.gnu.org-locations)
    (raw-content
     (append
-     %tls-settings
-     (list
-      "access_log  /var/log/nginx/https.access.log;"
-      "proxy_set_header X-Forwarded-Host $host;"
-      "proxy_set_header X-Forwarded-Port $server_port;"
-      "proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;"
-      ;; For client cert authentication
-      "ssl_client_certificate /etc/ssl-ca/certs/ca.crt;"
-      "ssl_crl /etc/ssl-ca/private/ca.crl;"
-      "ssl_verify_client on;")))
-   (locations
-    (let ((php-location (nginx-php-location)))
-      (list (nginx-location-configuration
-             (inherit php-location)
-             (body (cons "if ($ssl_client_verify != SUCCESS) { return 403; }"
-                         (append (nginx-location-configuration-body 
php-location)
-                                 (list "
-fastcgi_param PHP_VALUE \"post_max_size = 16M
-                          max_execution_time = 300\";
-"))))))))))
-
-(define %zabbix-nginx-local-server
-  (nginx-server-configuration
-   (inherit %zabbix-front-end-configuration-nginx)
-   (listen '("127.0.0.1:15412"))))
+        %tls-settings
+        (list
+         "add_header Content-Security-Policy \"frame-ancestors 'none'\";"
+
+         ;; TODO This works around NGinx using the epoch for the
+         ;; Last-Modified date, as well as the etag.
+         ;; See http://issues.guix.gnu.org/37207
+         "add_header Last-Modified \"\";"
+         "if_modified_since off;"
+         "etag off;"
+
+         "rewrite (.*)/$ $1/index.html;"
+         "access_log /var/log/nginx/guix-gnu-org.https.access.log;")))))
diff --git a/hydra/nginx/berlin.scm b/hydra/nginx/berlin.scm
index 37621d6..5cf3681 100644
--- a/hydra/nginx/berlin.scm
+++ b/hydra/nginx/berlin.scm
@@ -9,21 +9,11 @@
 
 (use-modules (gnu services web)
              (gnu services version-control)
-             (gnu packages monitoring))
+             (gnu packages monitoring)
+             (sysadmin nginx))
 
 
 
-(define* (le host #:optional privkey)
-  (string-append "/etc/letsencrypt/live/"
-                 host "/"
-                 (if privkey "privkey" "fullchain")
-                 ".pem"))
-
-(define (redirect old new)
-  (nginx-location-configuration
-   (uri (string-append "= " old)) ;= means highest priority
-   (body (list (string-append "return 301 " new ";\n")))))
-
 (define publish-robots.txt
   ;; Try to prevent good-faith crawlers from downloading substitutes.  Allow
   ;; indexing the root—which is expected to be static or cheap—to remain 
visible
@@ -148,19 +138,6 @@ Allow: /$\r
                            " =404;")
           "root /;")))))
 
-(define %tls-settings
-  (list
-   ;; Make sure SSL is disabled.
-   "ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;"
-   ;; Disable weak cipher suites.
-   "ssl_ciphers         HIGH:!aNULL:!MD5;"
-   "ssl_prefer_server_ciphers on;"
-
-   ;; Use our own DH parameters created with:
-   ;;    openssl dhparam -out dhparams.pem 2048
-   ;; as suggested at <https://weakdh.org/sysadmin.html>.
-   "ssl_dhparam         /etc/dhparams.pem;"))
-
 (define (berlin-locations publish-url)
   "Return nginx location blocks with 'guix publish' reachable at
 PUBLISH-URL."
@@ -197,635 +174,6 @@ PUBLISH-URL."
             (body
              (list "root /var/www/guix;"))))))
 
-(define guix.gnu.org-redirect-locations
-  (list
-   ;; Short URL for the installation script
-   (redirect "/install.sh" 
"https://git.savannah.gnu.org/cgit/guix.git/plain/etc/guix-install.sh";)
-   ;; What follows is a list of redirects for URLs that used to be
-   ;; available at gnu.org/s/guix--e.g.,
-   ;; <http://gnu.org/s/guix/news/porting-guix-and-guixsd.html>.
-   (redirect "/news/feed.xml" "/feeds/blog.atom")
-   (redirect "/news/porting-guix-and-guixsd.html" 
"/$lang/blog/2015/porting-guix-and-guixsd")
-   (redirect "/news/gnu-guix-welcomes-three-students-for-gsoc.html" 
"/$lang/blog/2015/gnu-guix-welcomes-three-students-for-gsoc")
-   (redirect "/news/gnu-guix-recruits-for-gsoc.html" 
"/$lang/blog/2015/gnu-guix-recruits-for-gsoc")
-   (redirect "/news/one-week-to-fosdem.html" 
"/$lang/blog/2014/one-week-to-fosdem")
-   (redirect "/news/gnu-dmd-02-released.html" 
"/$lang/blog/2014/gnu-dmd-02-released")
-   (redirect "/news/emacs-as-a-general-purpose-package-manager.html" 
"/$lang/blog/2014/emacs-as-a-general-purpose-package-manager")
-   (redirect "/news/join-gnu-guix-for-gsoc-2017.html" 
"/$lang/blog/2017/join-gnu-guix-for-gsoc-2017")
-   (redirect "/news/gnu-guix-05-released.html" 
"/$lang/blog/2013/gnu-guix-05-released")
-   (redirect "/news/guix-at-the-2014-gnu-hackers-meeting.html" 
"/$lang/blog/2014/guix-at-the-2014-gnu-hackers-meeting")
-   (redirect "/news/state-of-aarch64-on-guix.html" 
"/$lang/blog/2017/state-of-aarch64-on-guix")
-   (redirect "/news/coming-events.html" "/$lang/blog/2017/coming-events")
-   (redirect "/news/gnu-dmd-01-released.html" 
"/$lang/blog/2013/gnu-dmd-01-released")
-   (redirect "/news/announcing-guix-hpc.html" 
"/$lang/blog/2017/announcing-guix-hpc")
-   (redirect "/news/gnu-guix-looks-for-gsoc-students.html" 
"/$lang/blog/2014/gnu-guix-looks-for-gsoc-students")
-   (redirect "/news/guix-at-the-european-lisp-symposium.html" 
"/$lang/blog/2013/guix-at-the-european-lisp-symposium")
-   (redirect "/news/gnu-guix-08-released.html" 
"/$lang/blog/2014/gnu-guix-08-released")
-   (redirect "/news/gnu-guix-090-released.html" 
"/$lang/blog/2015/gnu-guix-090-released")
-   (redirect "/news/index.html" "/$lang/blog/")
-   (redirect "/news/gnu-guix-welcomes-four-students-for-gsoc.html" 
"/$lang/blog/2016/gnu-guix-welcomes-four-students-for-gsoc")
-   (redirect "/news/gnu-guix-081-released.html" 
"/$lang/blog/2015/gnu-guix-081-released")
-   (redirect "/news/timely-delivery-of-security-updates.html" 
"/$lang/blog/2016/timely-delivery-of-security-updates")
-   (redirect "/news/guix-at-openbio-codefest-2014.html" 
"/$lang/blog/2014/guix-at-openbio-codefest-2014")
-   (redirect "/news/gnu-guix-talk-in-boston-ma-usa-on-january-20th.html" 
"/$lang/blog/2016/gnu-guix-talk-in-boston-ma-usa-on-january-20th")
-   (redirect "/news/gnu-guix-at-fosdem.html" 
"/$lang/blog/2015/gnu-guix-at-fosdem")
-   (redirect "/news/gnu-guix-082-released.html" 
"/$lang/blog/2015/gnu-guix-082-released")
-   (redirect 
"/news/chris-webber-talks-about-guix-in-chicago-september-30th.html" 
"/$lang/blog/2015/chris-webber-talks-about-guix-in-chicago-september-30th")
-   (redirect "/news/back-from-the-gnu-hackers-meeting.html" 
"/$lang/blog/2013/back-from-the-gnu-hackers-meeting")
-   (redirect "/news/reproducible-build-summit-2nd-edition.html" 
"/$lang/blog/2016/reproducible-build-summit-2nd-edition")
-   (redirect "/news/gnu-guix-talk-in-rennes-france-november-9th.html" 
"/$lang/blog/2015/gnu-guix-talk-in-rennes-france-november-9th")
-   (redirect "/news/gnu-guix-01-released.html" 
"/$lang/blog/2013/gnu-guix-01-released")
-   (redirect "/news/guix-tox-talk-at-pyconfr-october-17th.html" 
"/$lang/blog/2015/guix-tox-talk-at-pyconfr-october-17th")
-   (redirect "/news/gnu-guix-and-guixsd-0.13.0-released.html" 
"/$lang/blog/2017/gnu-guix-and-guixsd-0.13.0-released")
-   (redirect "/news/guix-gets-cross-compilation-support.html" 
"/$lang/blog/2013/guix-gets-cross-compilation-support")
-   (redirect "/news/gnu-guix-06-released.html" 
"/$lang/blog/2014/gnu-guix-06-released")
-   (redirect "/news/meet-guix-at-fosdem.html" 
"/$lang/blog/2016/meet-guix-at-fosdem")
-   (redirect 
"/news/reproducible-and-user-controlled-software-environments-in-hpc-with-guix.html"
 
"/$lang/blog/2015/reproducible-and-user-controlled-software-environments-in-hpc-with-guix")
-   (redirect "/news/container-provisioning-with-guix.html" 
"/$lang/blog/2015/container-provisioning-with-guix")
-   (redirect "/news/guixsd-system-tests.html" 
"/$lang/blog/2016/guixsd-system-tests")
-   (redirect "/news/gnu-guix--guixsd-0100-released.html" 
"/$lang/blog/2016/gnu-guix--guixsd-0100-released")
-   (redirect "/news/gnu-guix-and-guixsd-0110-released.html" 
"/$lang/blog/2016/gnu-guix-and-guixsd-0110-released")
-   (redirect "/news/boot-to-guile.html" "/$lang/blog/2013/boot-to-guile")
-   (redirect "/news/gnu-guix-talk-at-opentechsummit-berlin-may-14th.html" 
"/$lang/blog/2015/gnu-guix-talk-at-opentechsummit-berlin-may-14th")
-   (redirect "/news/running-system-services-in-containers.html" 
"/$lang/blog/2017/running-system-services-in-containers")
-   (redirect "/news/growing-our-build-farm.html" 
"/$lang/blog/2016/growing-our-build-farm")
-   (redirect "/news/distro-of-the-linux-based-gnu-system-ported-to-mips.html" 
"/$lang/blog/2013/distro-of-the-linux-based-gnu-system-ported-to-mips")
-   (redirect "/news/guix-at-libreplanet-2016.html" 
"/$lang/blog/2016/guix-at-libreplanet-2016")
-   (redirect "/news/guix--gsoc.html" "/$lang/blog/2013/guix--gsoc")
-   (redirect "/news/service-composition-in-guixsd.html" 
"/$lang/blog/2015/service-composition-in-guixsd")
-   (redirect "/news/creating-bundles-with-guix-pack.html" 
"/$lang/blog/2017/creating-bundles-with-guix-pack")
-   (redirect "/news/back-from-the-european-lisp-symposium.html" 
"/$lang/blog/2013/back-from-the-european-lisp-symposium")
-   (redirect "/news/gnu-guix-04-released-happy-birthday-gnu.html" 
"/$lang/blog/2013/gnu-guix-04-released-happy-birthday-gnu")
-   (redirect "/news/reproducible-builds-a-status-update.html" 
"/$lang/blog/2017/reproducible-builds-a-status-update")
-   (redirect "/news/gnu-guix-083-released.html" 
"/$lang/blog/2015/gnu-guix-083-released")
-   (redirect "/news/join-gnu-guix-for-gsoc.html" 
"/$lang/blog/2016/join-gnu-guix-for-gsoc")
-   (redirect "/news/gnu-guix-and-guixsd-0120-released.html" 
"/$lang/blog/2016/gnu-guix-and-guixsd-0120-released")
-   (redirect "/news/meet-guix-at-fosdem-2017.html" 
"/$lang/blog/2017/meet-guix-at-fosdem-2017")
-   (redirect "/news/join-guix-for-an-on-line-hackathon-on-sep-28-29.html" 
"/$lang/blog/2013/join-guix-for-an-on-line-hackathon-on-sep-28-29")
-   (redirect "/news/gnome-in-guixsd.html" "/$lang/blog/2016/gnome-in-guixsd")
-   (redirect 
"/news/introducing-guix-a-package-manager-and-distro-for-gnu.html" 
"/$lang/blog/2012/introducing-guix-a-package-manager-and-distro-for-gnu")
-   (redirect "/news/gnu-guix-03-released.html" 
"/$lang/blog/2013/gnu-guix-03-released")
-   (redirect "/news/gnu-guix-07-released.html" 
"/$lang/blog/2014/gnu-guix-07-released")
-   (redirect "/news/gsoc-update.html" "/$lang/blog/2015/gsoc-update")
-   (redirect "/news/gnu-guix-02-released.html" 
"/$lang/blog/2013/gnu-guix-02-released")
-   (redirect 
"/news/guix-starts-fundraising-campaign-with-support-from-the-fsf.html" 
"/$lang/blog/2015/guix-starts-fundraising-campaign-with-support-from-the-fsf")
-   (redirect 
"/news/gnu-guix-ported-to-arm-and-other-niceties-of-the-new-year.html" 
"/$lang/blog/2015/gnu-guix-ported-to-arm-and-other-niceties-of-the-new-year")
-   (redirect "/news/reproducible-builds-a-means-to-an-end.html" 
"/$lang/blog/2015/reproducible-builds-a-means-to-an-end")
-   (redirect "/manual/html_node/Substitutes.html" 
"/manual/en/html_node/Substitutes.html")
-   (redirect "/manual/html_node/GNU-Free-Documentation-License.html" 
"/manual/en/html_node/GNU-Free-Documentation-License.html")
-   (redirect "/manual/html_node/The-Store-Monad.html" 
"/manual/en/html_node/The-Store-Monad.html")
-   (redirect "/manual/html_node/Running-Guix-Before-It-Is-Installed.html" 
"/manual/en/html_node/Running-Guix-Before-It-Is-Installed.html")
-   (redirect "/manual/html_node/rngd_002dservice.html" 
"/manual/en/html_node/rngd_002dservice.html")
-   (redirect "/manual/html_node/Data-Types-and-Pattern-Matching.html" 
"/manual/en/html_node/Data-Types-and-Pattern-Matching.html")
-   (redirect "/manual/html_node/Version-Numbers.html" 
"/manual/en/html_node/Version-Numbers.html")
-   (redirect "/manual/html_node/The-Perfect-Setup.html" 
"/manual/en/html_node/The-Perfect-Setup.html")
-   (redirect "/manual/html_node/G_002dExpressions.html" 
"/manual/en/html_node/G_002dExpressions.html")
-   (redirect "/manual/html_node/Programming-Paradigm.html" 
"/manual/en/html_node/Programming-Paradigm.html")
-   (redirect "/manual/html_node/Installing-GuixSD-in-a-VM.html" 
"/manual/en/html_node/Installing-GuixSD-in-a-VM.html")
-   (redirect "/manual/html_node/syslog_002dconfiguration_002dtype.html" 
"/manual/en/html_node/syslog_002dconfiguration_002dtype.html")
-   (redirect "/manual/html_node/Running-the-Test-Suite.html" 
"/manual/en/html_node/Running-the-Test-Suite.html")
-   (redirect "/manual/html_node/Coding-Style.html" 
"/manual/en/html_node/Coding-Style.html")
-   (redirect "/manual/html_node/Version-Control-Services.html" 
"/manual/en/html_node/Version-Control-Services.html")
-   (redirect "/manual/html_node/client_002dsubstitute_002durls.html" 
"/manual/en/html_node/client_002dsubstitute_002durls.html")
-   (redirect "/manual/html_node/Database-Services.html" 
"/manual/en/html_node/Database-Services.html")
-   (redirect "/manual/html_node/Invoking-guix-download.html" 
"/manual/en/html_node/Invoking-guix-download.html")
-   (redirect "/manual/html_node/Documentation.html" 
"/manual/en/html_node/Documentation.html")
-   (redirect "/manual/html_node/Package-Naming.html" 
"/manual/en/html_node/Package-Naming.html")
-   (redirect "/manual/html_node/Invoking-guix-hash.html" 
"/manual/en/html_node/Invoking-guix-hash.html")
-   (redirect "/manual/html_node/Audio-Services.html" 
"/manual/en/html_node/Audio-Services.html")
-   (redirect "/manual/html_node/Mapped-Devices.html" 
"/manual/en/html_node/Mapped-Devices.html")
-   (redirect "/manual/html_node/operating_002dsystem-Reference.html" 
"/manual/en/html_node/operating_002dsystem-Reference.html")
-   (redirect "/manual/html_node/Security-Updates.html" 
"/manual/en/html_node/Security-Updates.html")
-   (redirect "/manual/html_node/Java-Packages.html" 
"/manual/en/html_node/Java-Packages.html")
-   (redirect "/manual/html_node/user_002daccount_002dpassword.html" 
"/manual/en/html_node/user_002daccount_002dpassword.html")
-   (redirect "/manual/html_node/System-Installation.html" 
"/manual/en/html_node/System-Installation.html")
-   (redirect "/manual/html_node/Installation.html" 
"/manual/en/html_node/Installation.html")
-   (redirect "/manual/html_node/Modules.html" 
"/manual/en/html_node/Modules.html")
-   (redirect "/manual/html_node/File-Systems.html" 
"/manual/en/html_node/File-Systems.html")
-   (redirect "/manual/html_node/Invoking-guix-gc.html" 
"/manual/en/html_node/Invoking-guix-gc.html")
-   (redirect "/manual/html_node/package_002dpropagated_002dinputs.html" 
"/manual/en/html_node/package_002dpropagated_002dinputs.html")
-   (redirect "/manual/html_node/Invoking-guix-lint.html" 
"/manual/en/html_node/Invoking-guix-lint.html")
-   (redirect "/manual/html_node/Invoking-guix-pull.html" 
"/manual/en/html_node/Invoking-guix-pull.html")
-   (redirect "/manual/html_node/Invoking-guix_002ddaemon.html" 
"/manual/en/html_node/Invoking-guix_002ddaemon.html")
-   (redirect "/manual/html_node/Locales.html" 
"/manual/en/html_node/Locales.html")
-   (redirect "/manual/html_node/Using-the-Configuration-System.html" 
"/manual/en/html_node/Using-the-Configuration-System.html")
-   (redirect "/manual/html_node/X_002e509-Certificates.html" 
"/manual/en/html_node/X_002e509-Certificates.html")
-   (redirect "/manual/html_node/guix_002dconfiguration_002dtype.html" 
"/manual/en/html_node/guix_002dconfiguration_002dtype.html")
-   (redirect "/manual/html_node/USB-Stick-and-DVD-Installation.html" 
"/manual/en/html_node/USB-Stick-and-DVD-Installation.html")
-   (redirect "/manual/html_node/Software-Freedom.html" 
"/manual/en/html_node/Software-Freedom.html")
-   (redirect "/manual/html_node/Building-the-Installation-Image.html" 
"/manual/en/html_node/Building-the-Installation-Image.html")
-   (redirect "/manual/html_node/Running-GuixSD-in-a-VM.html" 
"/manual/en/html_node/Running-GuixSD-in-a-VM.html")
-   (redirect "/manual/html_node/Debugging-Build-Failures.html" 
"/manual/en/html_node/Debugging-Build-Failures.html")
-   (redirect "/manual/html_node/daemon_002dsubstitute_002durls.html" 
"/manual/en/html_node/daemon_002dsubstitute_002durls.html")
-   (redirect "/manual/html_node/Virtualization-Services.html" 
"/manual/en/html_node/Virtualization-Services.html")
-   (redirect "/manual/html_node/Fonts.html" "/manual/en/html_node/Fonts.html")
-   (redirect "/manual/html_node/Monitoring-Services.html" 
"/manual/en/html_node/Monitoring-Services.html")
-   (redirect "/manual/html_node/Binary-Installation.html" 
"/manual/en/html_node/Binary-Installation.html")
-   (redirect "/manual/html_node/Messaging-Services.html" 
"/manual/en/html_node/Messaging-Services.html")
-   (redirect "/manual/html_node/X-Window.html" 
"/manual/en/html_node/X-Window.html")
-   (redirect "/manual/html_node/Service-Types-and-Services.html" 
"/manual/en/html_node/Service-Types-and-Services.html")
-   (redirect "/manual/html_node/Introduction.html" 
"/manual/en/html_node/Introduction.html")
-   (redirect "/manual/html_node/Hardware-Considerations.html" 
"/manual/en/html_node/Hardware-Considerations.html")
-   (redirect "/manual/html_node/System-Configuration.html" 
"/manual/en/html_node/System-Configuration.html")
-   (redirect "/manual/html_node/VPN-Services.html" 
"/manual/en/html_node/VPN-Services.html")
-   (redirect "/manual/html_node/Invoking-guix-system.html" 
"/manual/en/html_node/Invoking-guix-system.html")
-   (redirect "/manual/html_node/index.html" "/manual/en/html_node/index.html")
-   (redirect "/manual/html_node/package-Reference.html" 
"/manual/en/html_node/package-Reference.html")
-   (redirect "/manual/html_node/Sending-a-Patch-Series.html" 
"/manual/en/html_node/Sending-a-Patch-Series.html")
-   (redirect 
"/manual/html_node/package_002dcmd_002dpropagated_002dinputs.html" 
"/manual/en/html_node/package_002dcmd_002dpropagated_002dinputs.html")
-   (redirect "/manual/html_node/Invoking-guix-refresh.html" 
"/manual/en/html_node/Invoking-guix-refresh.html")
-   (redirect "/manual/html_node/GNU-Distribution.html" 
"/manual/en/html_node/GNU-Distribution.html")
-   (redirect "/manual/html_node/Name-Service-Switch.html" 
"/manual/en/html_node/Name-Service-Switch.html")
-   (redirect "/manual/html_node/The-Store.html" 
"/manual/en/html_node/The-Store.html")
-   (redirect "/manual/html_node/Common-Build-Options.html" 
"/manual/en/html_node/Common-Build-Options.html")
-   (redirect "/manual/html_node/Invoking-guix-import.html" 
"/manual/en/html_node/Invoking-guix-import.html")
-   (redirect "/manual/html_node/Invoking-guix-edit.html" 
"/manual/en/html_node/Invoking-guix-edit.html")
-   (redirect "/manual/html_node/Network-File-System.html" 
"/manual/en/html_node/Network-File-System.html")
-   (redirect "/manual/html_node/Miscellaneous-Services.html" 
"/manual/en/html_node/Miscellaneous-Services.html")
-   (redirect "/manual/html_node/Daemon-Offload-Setup.html" 
"/manual/en/html_node/Daemon-Offload-Setup.html")
-   (redirect "/manual/html_node/Features.html" 
"/manual/en/html_node/Features.html")
-   (redirect "/manual/html_node/guix_002dpublish_002dservice_002dtype.html" 
"/manual/en/html_node/guix_002dpublish_002dservice_002dtype.html")
-   (redirect "/manual/html_node/Invoking-guix-pack.html" 
"/manual/en/html_node/Invoking-guix-pack.html")
-   (redirect "/manual/html_node/Contributing.html" 
"/manual/en/html_node/Contributing.html")
-   (redirect "/manual/html_node/fallback_002doption.html" 
"/manual/en/html_node/fallback_002doption.html")
-   (redirect "/manual/html_node/Power-management-Services.html" 
"/manual/en/html_node/Power-Management-Services.html")
-   (redirect "/manual/html_node/build_002dcheck.html" 
"/manual/en/html_node/build_002dcheck.html")
-   (redirect "/manual/html_node/Invoking-guix-package.html" 
"/manual/en/html_node/Invoking-guix-package.html")
-   (redirect "/manual/html_node/Mail-Services.html" 
"/manual/en/html_node/Mail-Services.html")
-   (redirect "/manual/html_node/Concept-Index.html" 
"/manual/en/html_node/Concept-Index.html")
-   (redirect "/manual/html_node/Build-Environment-Setup.html" 
"/manual/en/html_node/Build-Environment-Setup.html")
-   (redirect "/manual/html_node/Printing-Services.html" 
"/manual/en/html_node/Printing-Services.html")
-   (redirect "/manual/html_node/Invoking-guix-build.html" 
"/manual/en/html_node/Invoking-guix-build.html")
-   (redirect "/manual/html_node/Programming-Interface.html" 
"/manual/en/html_node/Programming-Interface.html")
-   (redirect "/manual/html_node/profile_002dmanifest.html" 
"/manual/en/html_node/profile_002dmanifest.html")
-   (redirect "/manual/html_node/Packaging-Guidelines.html" 
"/manual/en/html_node/Packaging-Guidelines.html")
-   (redirect "/manual/html_node/Kerberos-Services.html" 
"/manual/en/html_node/Kerberos-Services.html")
-   (redirect "/manual/html_node/Invoking-guix-graph.html" 
"/manual/en/html_node/Invoking-guix-graph.html")
-   (redirect "/manual/html_node/Invoking-guix-container.html" 
"/manual/en/html_node/Invoking-guix-container.html")
-   (redirect "/manual/html_node/Derivations.html" 
"/manual/en/html_node/Derivations.html")
-   (redirect "/manual/html_node/Programming-Index.html" 
"/manual/en/html_node/Programming-Index.html")
-   (redirect "/manual/html_node/Setting-Up-the-Daemon.html" 
"/manual/en/html_node/Setting-Up-the-Daemon.html")
-   (redirect "/manual/html_node/Continuous-Integration.html" 
"/manual/en/html_node/Continuous-Integration.html")
-   (redirect "/manual/html_node/User-Accounts.html" 
"/manual/en/html_node/User-Accounts.html")
-   (redirect "/manual/html_node/guix-system-vm.html" 
"/manual/en/html_node/guix-system-vm.html")
-   (redirect "/manual/html_node/Invoking-guix-weather.html" 
"/manual/en/html_node/Invoking-guix-weather.html")
-   (redirect "/manual/html_node/USB-Stick-Installation.html" 
"/manual/en/html_node/USB-Stick-Installation.html")
-   (redirect "/manual/html_node/Telephony-Services.html" 
"/manual/en/html_node/Telephony-Services.html")
-   (redirect "/manual/html_node/Additional-Build-Options.html" 
"/manual/en/html_node/Additional-Build-Options.html")
-   (redirect "/manual/html_node/Requirements.html" 
"/manual/en/html_node/Requirements.html")
-   (redirect "/manual/html_node/Acknowledgments.html" 
"/manual/en/html_node/Acknowledgments.html")
-   (redirect "/manual/html_node/Formatting-Code.html" 
"/manual/en/html_node/Formatting-Code.html")
-   (redirect "/manual/html_node/Certificate-Services.html" 
"/manual/en/html_node/Certificate-Services.html")
-   (redirect "/manual/html_node/Invoking-guix-copy.html" 
"/manual/en/html_node/Invoking-guix-copy.html")
-   (redirect "/manual/html_node/Package-Modules.html" 
"/manual/en/html_node/Package-Modules.html")
-   (redirect "/manual/html_node/Proxy-Settings.html" 
"/manual/en/html_node/Proxy-Settings.html")
-   (redirect "/manual/html_node/locales_002dand_002dlocpath.html" 
"/manual/en/html_node/locales_002dand_002dlocpath.html")
-   (redirect "/manual/html_node/Substitute-Server-Authorization.html" 
"/manual/en/html_node/Substitute-Server-Authorization.html")
-   (redirect "/manual/html_node/Setuid-Programs.html" 
"/manual/en/html_node/Setuid-Programs.html")
-   (redirect "/manual/html_node/Bootstrapping.html" 
"/manual/en/html_node/Bootstrapping.html")
-   (redirect "/manual/html_node/Defining-Services.html" 
"/manual/en/html_node/Defining-Services.html")
-   (redirect "/manual/html_node/pam_002dlimits_002dservice.html" 
"/manual/en/html_node/pam_002dlimits_002dservice.html")
-   (redirect "/manual/html_node/Desktop-Services.html" 
"/manual/en/html_node/Desktop-Services.html")
-   (redirect "/manual/html_node/Utilities.html" 
"/manual/en/html_node/Utilities.html")
-   (redirect "/manual/html_node/Services.html" 
"/manual/en/html_node/Services.html")
-   (redirect "/manual/html_node/Limitations.html" 
"/manual/en/html_node/Limitations.html")
-   (redirect "/manual/html_node/Invoking-guix-size.html" 
"/manual/en/html_node/Invoking-guix-size.html")
-   (redirect "/manual/html_node/Shepherd-Services.html" 
"/manual/en/html_node/Shepherd-Services.html")
-   (redirect "/manual/html_node/system_002dshepherd_002dgraph.html" 
"/manual/en/html_node/system_002dshepherd_002dgraph.html")
-   (redirect "/manual/html_node/Invoking-guix-environment.html" 
"/manual/en/html_node/Invoking-guix-environment.html")
-   (redirect "/manual/html_node/Invoking-guix-publish.html" 
"/manual/en/html_node/Invoking-guix-publish.html")
-   (redirect "/manual/html_node/Log-Rotation.html" 
"/manual/en/html_node/Log-Rotation.html")
-   (redirect "/manual/html_node/Building-from-Git.html" 
"/manual/en/html_node/Building-from-Git.html")
-   (redirect "/manual/html_node/Defining-Packages.html" 
"/manual/en/html_node/Defining-Packages.html")
-   (redirect "/manual/html_node/DNS-Services.html" 
"/manual/en/html_node/DNS-Services.html")
-   (redirect "/manual/html_node/Bootloader-Configuration.html" 
"/manual/en/html_node/Bootloader-Configuration.html")
-   (redirect "/manual/html_node/Invoking-guix-challenge.html" 
"/manual/en/html_node/Invoking-guix-challenge.html")
-   (redirect 
"/manual/html_node/nginx_002dlocation_002dconfiguration-body.html" 
"/manual/en/html_node/nginx_002dlocation_002dconfiguration-body.html")
-   (redirect "/manual/html_node/Proceeding-with-the-Installation.html" 
"/manual/en/html_node/Proceeding-with-the-Installation.html")
-   (redirect "/manual/html_node/Initial-RAM-Disk.html" 
"/manual/en/html_node/Initial-RAM-Disk.html")
-   (redirect "/manual/html_node/syslog_002dservice.html" 
"/manual/en/html_node/syslog_002dservice.html")
-   (redirect "/manual/html_node/Preparing-for-Installation.html" 
"/manual/en/html_node/Preparing-for-Installation.html")
-   (redirect "/manual/html_node/Application-Setup.html" 
"/manual/en/html_node/Application-Setup.html")
-   (redirect "/manual/html_node/Service-Composition.html" 
"/manual/en/html_node/Service-Composition.html")
-   (redirect "/manual/html_node/Packages-with-Multiple-Outputs.html" 
"/manual/en/html_node/Packages-with-Multiple-Outputs.html")
-   (redirect "/manual/html_node/Submitting-Patches.html" 
"/manual/en/html_node/Submitting-Patches.html")
-   (redirect "/manual/html_node/Substitution-Failure.html" 
"/manual/en/html_node/Substitution-Failure.html")
-   (redirect "/manual/html_node/Porting.html" 
"/manual/en/html_node/Porting.html")
-   (redirect "/manual/html_node/Web-Services.html" 
"/manual/en/html_node/Web-Services.html")
-   (redirect "/manual/html_node/Build-Systems.html" 
"/manual/en/html_node/Build-Systems.html")
-   (redirect "/manual/html_node/Python-Modules.html" 
"/manual/en/html_node/Python-Modules.html")
-   (redirect "/manual/html_node/On-Trusting-Binaries.html" 
"/manual/en/html_node/On-Trusting-Binaries.html")
-   (redirect "/manual/html_node/Synopses-and-Descriptions.html" 
"/manual/en/html_node/Synopses-and-Descriptions.html")
-   (redirect "/manual/html_node/Invoking-guix-archive.html" 
"/manual/en/html_node/Invoking-guix-archive.html")
-   (redirect "/manual/html_node/Package-Transformation-Options.html" 
"/manual/en/html_node/Package-Transformation-Options.html")
-   (redirect "/manual/html_node/Perl-Modules.html" 
"/manual/en/html_node/Perl-Modules.html")
-   (redirect "/manual/html_node/Base-Services.html" 
"/manual/en/html_node/Base-Services.html")
-   (redirect "/manual/html_node/origin-Reference.html" 
"/manual/en/html_node/origin-Reference.html")
-   (redirect "/manual/html_node/Substitute-Authentication.html" 
"/manual/en/html_node/Substitute-Authentication.html")
-   (redirect "/manual/html_node/Service-Reference.html" 
"/manual/en/html_node/Service-Reference.html")
-   (redirect "/manual/html_node/system_002dextension_002dgraph.html" 
"/manual/en/html_node/system_002dextension_002dgraph.html")
-   (redirect "/manual/html_node/Installing-Debugging-Files.html" 
"/manual/en/html_node/Installing-Debugging-Files.html")
-   (redirect "/manual/html_node/Official-Substitute-Server.html" 
"/manual/en/html_node/Official-Substitute-Server.html")
-   (redirect "/manual/html_node/Scheduled-Job-Execution.html" 
"/manual/en/html_node/Scheduled-Job-Execution.html")
-   (redirect "/manual/html_node/Package-Management.html" 
"/manual/en/html_node/Package-Management.html")
-   (redirect "/manual/html_node/Networking-Services.html" 
"/manual/en/html_node/Networking-Services.html")
-   (redirect "/manual/html_node" "en/html_node")
-   (redirect "/manual/guix.html" "en/guix.html")
-   (redirect "/manual/en/html_node/Installing-GuixSD-in-a-VM.html" 
"Installing-Guix-in-a-VM.html")
-   (redirect "/manual/en/html_node/Running-GuixSD-in-a-VM.html"
-             "Running-Guix-in-a-VM.html")
-   ;; Old URLs not ending in a slash like https://guix.gnu.org/graphics.
-   (redirect "/about" "/$lang/about/")
-   (redirect "/blog" "/$lang/blog/")
-   (redirect "/blog/2006/purely-functional-software-deployment-model" 
"/$lang/blog/2006/purely-functional-software-deployment-model/")
-   (redirect "/blog/2012/functional-package-management-for-the-people" 
"/$lang/blog/2012/functional-package-management-for-the-people/")
-   (redirect 
"/blog/2012/introducing-guix-a-package-manager-and-distro-for-gnu" 
"/$lang/blog/2012/introducing-guix-a-package-manager-and-distro-for-gnu/")
-   (redirect "/blog/2013/back-from-the-european-lisp-symposium" 
"/$lang/blog/2013/back-from-the-european-lisp-symposium/")
-   (redirect "/blog/2013/back-from-the-gnu-hackers-meeting" 
"/$lang/blog/2013/back-from-the-gnu-hackers-meeting/")
-   (redirect "/blog/2013/boot-to-guile" "/$lang/blog/2013/boot-to-guile/")
-   (redirect "/blog/2013/distro-of-the-linux-based-gnu-system-ported-to-mips" 
"/$lang/blog/2013/distro-of-the-linux-based-gnu-system-ported-to-mips/")
-   (redirect "/blog/2013/gnu-dmd-01-released" 
"/$lang/blog/2013/gnu-dmd-01-released/")
-   (redirect "/blog/2013/gnu-guix-01-released" 
"/$lang/blog/2013/gnu-guix-01-released/")
-   (redirect "/blog/2013/gnu-guix-02-released" 
"/$lang/blog/2013/gnu-guix-02-released/")
-   (redirect "/blog/2013/gnu-guix-03-released" 
"/$lang/blog/2013/gnu-guix-03-released/")
-   (redirect "/blog/2013/gnu-guix-04-released-happy-birthday-gnu" 
"/$lang/blog/2013/gnu-guix-04-released-happy-birthday-gnu/")
-   (redirect "/blog/2013/gnu-guix-05-released" 
"/$lang/blog/2013/gnu-guix-05-released/")
-   (redirect "/blog/2013/guix-at-the-european-lisp-symposium" 
"/$lang/blog/2013/guix-at-the-european-lisp-symposium/")
-   (redirect "/blog/2013/guix-gets-cross-compilation-support" 
"/$lang/blog/2013/guix-gets-cross-compilation-support/")
-   (redirect "/blog/2013/guix--gsoc" "/$lang/blog/2013/guix--gsoc/")
-   (redirect "/blog/2013/join-guix-for-an-on-line-hackathon-on-sep-28-29" 
"/$lang/blog/2013/join-guix-for-an-on-line-hackathon-on-sep-28-29/")
-   (redirect "/blog/2014/emacs-as-a-general-purpose-package-manager" 
"/$lang/blog/2014/emacs-as-a-general-purpose-package-manager/")
-   (redirect "/blog/2014/gnu-dmd-02-released" 
"/$lang/blog/2014/gnu-dmd-02-released/")
-   (redirect "/blog/2014/gnu-guix-06-released" 
"/$lang/blog/2014/gnu-guix-06-released/")
-   (redirect "/blog/2014/gnu-guix-07-released" 
"/$lang/blog/2014/gnu-guix-07-released/")
-   (redirect "/blog/2014/gnu-guix-08-released" 
"/$lang/blog/2014/gnu-guix-08-released/")
-   (redirect "/blog/2014/gnu-guix-looks-for-gsoc-students" 
"/$lang/blog/2014/gnu-guix-looks-for-gsoc-students/")
-   (redirect "/blog/2014/guix-at-openbio-codefest-2014" 
"/$lang/blog/2014/guix-at-openbio-codefest-2014/")
-   (redirect "/blog/2014/guix-at-the-2014-gnu-hackers-meeting" 
"/$lang/blog/2014/guix-at-the-2014-gnu-hackers-meeting/")
-   (redirect "/blog/2014/join-us-for-a-guix-hackathon-on-sep-27-28" 
"/$lang/blog/2014/join-us-for-a-guix-hackathon-on-sep-27-28/")
-   (redirect "/blog/2014/one-week-to-fosdem" 
"/$lang/blog/2014/one-week-to-fosdem/")
-   (redirect 
"/blog/2015/chris-webber-talks-about-guix-in-chicago-september-30th" 
"/$lang/blog/2015/chris-webber-talks-about-guix-in-chicago-september-30th/")
-   (redirect "/blog/2015/container-provisioning-with-guix" 
"/$lang/blog/2015/container-provisioning-with-guix/")
-   (redirect "/blog/2015/gnu-guix-081-released" 
"/$lang/blog/2015/gnu-guix-081-released/")
-   (redirect "/blog/2015/gnu-guix-082-released" 
"/$lang/blog/2015/gnu-guix-082-released/")
-   (redirect "/blog/2015/gnu-guix-083-released" 
"/$lang/blog/2015/gnu-guix-083-released/")
-   (redirect "/blog/2015/gnu-guix-090-released" 
"/$lang/blog/2015/gnu-guix-090-released/")
-   (redirect "/blog/2015/gnu-guix-at-fosdem" 
"/$lang/blog/2015/gnu-guix-at-fosdem/")
-   (redirect 
"/blog/2015/gnu-guix-ported-to-arm-and-other-niceties-of-the-new-year" 
"/$lang/blog/2015/gnu-guix-ported-to-arm-and-other-niceties-of-the-new-year/")
-   (redirect "/blog/2015/gnu-guix-recruits-for-gsoc" 
"/$lang/blog/2015/gnu-guix-recruits-for-gsoc/")
-   (redirect "/blog/2015/gnu-guix-talk-at-opentechsummit-berlin-may-14th" 
"/$lang/blog/2015/gnu-guix-talk-at-opentechsummit-berlin-may-14th/")
-   (redirect "/blog/2015/gnu-guix-talk-in-rennes-france-november-9th" 
"/$lang/blog/2015/gnu-guix-talk-in-rennes-france-november-9th/")
-   (redirect "/blog/2015/gnu-guix-welcomes-three-students-for-gsoc" 
"/$lang/blog/2015/gnu-guix-welcomes-three-students-for-gsoc/")
-   (redirect "/blog/2015/gsoc-update" "/$lang/blog/2015/gsoc-update/")
-   (redirect 
"/blog/2015/guix-starts-fundraising-campaign-with-support-from-the-fsf" 
"/$lang/blog/2015/guix-starts-fundraising-campaign-with-support-from-the-fsf/")
-   (redirect "/blog/2015/guix-tox-talk-at-pyconfr-october-17th" 
"/$lang/blog/2015/guix-tox-talk-at-pyconfr-october-17th/")
-   (redirect "/blog/2015/porting-guix-and-guixsd" 
"/$lang/blog/2015/porting-guix-and-guixsd/")
-   (redirect 
"/blog/2015/reproducible-and-user-controlled-software-environments-in-hpc-with-guix"
 
"/$lang/blog/2015/reproducible-and-user-controlled-software-environments-in-hpc-with-guix/")
-   (redirect "/blog/2015/reproducible-builds-a-means-to-an-end" 
"/$lang/blog/2015/reproducible-builds-a-means-to-an-end/")
-   (redirect "/blog/2015/service-composition-in-guixsd" 
"/$lang/blog/2015/service-composition-in-guixsd/")
-   (redirect "/blog/2016/back-from-cufp-2016" 
"/$lang/blog/2016/back-from-cufp-2016/")
-   (redirect "/blog/2016/back-from-dconf-2016" 
"/$lang/blog/2016/back-from-dconf-2016/")
-   (redirect "/blog/2016/back-from-gbcuw-2016" 
"/$lang/blog/2016/back-from-gbcuw-2016/")
-   (redirect "/blog/2016/back-from-the-gnu-hackers-meeting-2016" 
"/$lang/blog/2016/back-from-the-gnu-hackers-meeting-2016/")
-   (redirect "/blog/2016/back-from-the-scheme-workshop-2016" 
"/$lang/blog/2016/back-from-the-scheme-workshop-2016/")
-   (redirect "/blog/2016/gnome-in-guixsd" "/$lang/blog/2016/gnome-in-guixsd/")
-   (redirect "/blog/2016/gnu-guix-and-guixsd-0110-released" 
"/$lang/blog/2016/gnu-guix-and-guixsd-0110-released/")
-   (redirect "/blog/2016/gnu-guix-and-guixsd-0120-released" 
"/$lang/blog/2016/gnu-guix-and-guixsd-0120-released/")
-   (redirect "/blog/2016/gnu-guix--guixsd-0100-released" 
"/$lang/blog/2016/gnu-guix--guixsd-0100-released/")
-   (redirect "/blog/2016/gnu-guix-on-hacker-public-radio" 
"/$lang/blog/2016/gnu-guix-on-hacker-public-radio/")
-   (redirect "/blog/2016/gnu-guix-talk-in-boston-ma-usa-on-january-20th" 
"/$lang/blog/2016/gnu-guix-talk-in-boston-ma-usa-on-january-20th/")
-   (redirect "/blog/2016/gnu-guix-welcomes-four-students-for-gsoc" 
"/$lang/blog/2016/gnu-guix-welcomes-four-students-for-gsoc/")
-   (redirect "/blog/2016/growing-our-build-farm" 
"/$lang/blog/2016/growing-our-build-farm/")
-   (redirect "/blog/2016/guix-at-libreplanet-2016" 
"/$lang/blog/2016/guix-at-libreplanet-2016/")
-   (redirect "/blog/2016/guixsd-system-tests" 
"/$lang/blog/2016/guixsd-system-tests/")
-   (redirect "/blog/2016/join-gnu-guix-for-gsoc" 
"/$lang/blog/2016/join-gnu-guix-for-gsoc/")
-   (redirect "/blog/2016/meet-guix-at-fosdem" 
"/$lang/blog/2016/meet-guix-at-fosdem/")
-   (redirect "/blog/2016/reproducible-build-summit-2nd-edition" 
"/$lang/blog/2016/reproducible-build-summit-2nd-edition/")
-   (redirect "/blog/2016/timely-delivery-of-security-updates" 
"/$lang/blog/2016/timely-delivery-of-security-updates/")
-   (redirect "/blog/2017/announcing-guix-hpc" 
"/$lang/blog/2017/announcing-guix-hpc/")
-   (redirect "/blog/2017/back-from-bob-konferenz-2017" 
"/$lang/blog/2017/back-from-bob-konferenz-2017/")
-   (redirect "/blog/2017/back-from-bosc-2017" 
"/$lang/blog/2017/back-from-bosc-2017/")
-   (redirect "/blog/2017/back-from-fosdem-2017" 
"/$lang/blog/2017/back-from-fosdem-2017/")
-   (redirect "/blog/2017/back-from-gpce" "/$lang/blog/2017/back-from-gpce/")
-   (redirect "/blog/2017/back-from-rse-2017" 
"/$lang/blog/2017/back-from-rse-2017/")
-   (redirect "/blog/2017/coming-events" "/$lang/blog/2017/coming-events/")
-   (redirect "/blog/2017/creating-bundles-with-guix-pack" 
"/$lang/blog/2017/creating-bundles-with-guix-pack/")
-   (redirect "/blog/2017/gnu-guix-and-guixsd-0.13.0-released" 
"/$lang/blog/2017/gnu-guix-and-guixsd-0.13.0-released/")
-   (redirect "/blog/2017/gnu-guix-and-guixsd-0.14.0-released" 
"/$lang/blog/2017/gnu-guix-and-guixsd-0.14.0-released/")
-   (redirect "/blog/2017/join-gnu-guix-for-gsoc-2017" 
"/$lang/blog/2017/join-gnu-guix-for-gsoc-2017/")
-   (redirect "/blog/2017/meet-guix-at-fosdem-2017" 
"/$lang/blog/2017/meet-guix-at-fosdem-2017/")
-   (redirect "/blog/2017/porting-guixsd-to-armv7" 
"/$lang/blog/2017/porting-guixsd-to-armv7/")
-   (redirect "/blog/2017/reproducible-builds-a-status-update" 
"/$lang/blog/2017/reproducible-builds-a-status-update/")
-   (redirect "/blog/2017/running-system-services-in-containers" 
"/$lang/blog/2017/running-system-services-in-containers/")
-   (redirect "/blog/2017/state-of-aarch64-on-guix" 
"/$lang/blog/2017/state-of-aarch64-on-guix/")
-   (redirect "/blog/2018/aarch64-build-machines-donated" 
"/$lang/blog/2018/aarch64-build-machines-donated/")
-   (redirect "/blog/2018/a-packaging-tutorial-for-guix" 
"/$lang/blog/2018/a-packaging-tutorial-for-guix/")
-   (redirect "/blog/2018/back-from-seagl-2018" 
"/$lang/blog/2018/back-from-seagl-2018/")
-   (redirect "/blog/2018/bootstrapping-rust" 
"/$lang/blog/2018/bootstrapping-rust/")
-   (redirect "/blog/2018/customize-guixsd-use-stock-ssh-agent-everywhere" 
"/$lang/blog/2018/customize-guixsd-use-stock-ssh-agent-everywhere/")
-   (redirect "/blog/2018/gnu-guix-and-guixsd-0.15.0-released" 
"/$lang/blog/2018/gnu-guix-and-guixsd-0.15.0-released/")
-   (redirect "/blog/2018/gnu-guix-and-guixsd-0.16.0-released" 
"/$lang/blog/2018/gnu-guix-and-guixsd-0.16.0-released/")
-   (redirect 
"/blog/2018/gnu-guix-receives-donation-from-the-handshake-project" 
"/$lang/blog/2018/gnu-guix-receives-donation-from-the-handshake-project/")
-   (redirect "/blog/2018/gsoc-2018-report-cuirass-web-interface" 
"/$lang/blog/2018/gsoc-2018-report-cuirass-web-interface/")
-   (redirect "/blog/2018/guix-on-android" "/$lang/blog/2018/guix-on-android/")
-   (redirect "/blog/2018/guix--reproducible-builds-at-libreplanet-2018" 
"/$lang/blog/2018/guix--reproducible-builds-at-libreplanet-2018/")
-   (redirect "/blog/2018/guix-welcomes-outreachy-gsoc-and-guix-hpc-interns" 
"/$lang/blog/2018/guix-welcomes-outreachy-gsoc-and-guix-hpc-interns/")
-   (redirect "/blog/2018/join-gnu-guix-outreachy-gsoc" 
"/$lang/blog/2018/join-gnu-guix-outreachy-gsoc/")
-   (redirect "/blog/2018/join-gnu-guix-through-outreachy" 
"/$lang/blog/2018/join-gnu-guix-through-outreachy/")
-   (redirect "/blog/2018/meet-guix-at-fosdem-2018" 
"/$lang/blog/2018/meet-guix-at-fosdem-2018/")
-   (redirect "/blog/2018/multi-dimensional-transactions-and-rollbacks-oh-my" 
"/$lang/blog/2018/multi-dimensional-transactions-and-rollbacks-oh-my/")
-   (redirect 
"/blog/2018/paper-on-reproducible-bioinformatics-pipelines-with-guix" 
"/$lang/blog/2018/paper-on-reproducible-bioinformatics-pipelines-with-guix/")
-   (redirect "/blog/2018/reproducible-builds-summit-4th-edition" 
"/$lang/blog/2018/reproducible-builds-summit-4th-edition/")
-   (redirect "/blog/2018/tarballs-the-ultimate-container-image-format" 
"/$lang/blog/2018/tarballs-the-ultimate-container-image-format/")
-   (redirect "/blog/2018/upcoming-talk-everyday-use-of-gnu-guix" 
"/$lang/blog/2018/upcoming-talk-everyday-use-of-gnu-guix/")
-   (redirect 
"/blog/2019/connecting-reproducible-deployment-to-a-long-term-source-code-archive"
 
"/$lang/blog/2019/connecting-reproducible-deployment-to-a-long-term-source-code-archive/")
-   (redirect 
"/blog/2019/creating-and-using-a-custom-linux-kernel-on-guix-system" 
"/$lang/blog/2019/creating-and-using-a-custom-linux-kernel-on-guix-system/")
-   (redirect "/blog/2019/documentation-video-creation" 
"/$lang/blog/2019/documentation-video-creation/")
-   (redirect "/blog/2019/gnu-guix-1.0.0-released" 
"/$lang/blog/2019/gnu-guix-1.0.0-released/")
-   (redirect "/blog/2019/gnu-guix-1.0.1-released" 
"/$lang/blog/2019/gnu-guix-1.0.1-released/")
-   (redirect "/blog/2019/gnu-guix-maintainer-collective-expands" 
"/$lang/blog/2019/gnu-guix-maintainer-collective-expands/")
-   (redirect "/blog/2019/guix-days-bootstrapping-arm" 
"/$lang/blog/2019/guix-days-bootstrapping-arm/")
-   (redirect "/blog/2019/guix-on-an-arm-board" 
"/$lang/blog/2019/guix-on-an-arm-board/")
-   (redirect "/blog/2019/guix-profiles-in-practice" 
"/$lang/blog/2019/guix-profiles-in-practice/")
-   (redirect "/blog/2019/guix-reduces-bootstrap-seed-by-50" 
"/$lang/blog/2019/guix-reduces-bootstrap-seed-by-50/")
-   (redirect 
"/blog/2019/insecure-permissions-on-profile-directory-cve-2019-18192" 
"/$lang/blog/2019/insecure-permissions-on-profile-directory-cve-2019-18192/")
-   (redirect "/blog/2019/join-gnu-guix-through-outreachy" 
"/$lang/blog/2019/join-gnu-guix-through-outreachy/")
-   (redirect "/blog/2019/joint-statement-on-the-gnu-project" 
"/$lang/blog/2019/joint-statement-on-the-gnu-project/")
-   (redirect "/blog/2019/managing-servers-with-gnu-guix-a-tutorial" 
"/$lang/blog/2019/managing-servers-with-gnu-guix-a-tutorial/")
-   (redirect "/blog/2019/meet-guix-at-fosdem-2019" 
"/$lang/blog/2019/meet-guix-at-fosdem-2019/")
-   (redirect "/blog/2019/qa-on-non-intel-at-guix-days" 
"/$lang/blog/2019/qa-on-non-intel-at-guix-days/")
-   (redirect "/blog/2019/reproducible-builds-summit-5th-edition" 
"/$lang/blog/2019/reproducible-builds-summit-5th-edition/")
-   (redirect "/blog/2019/running-a-guix-xfce-desktop-on-centos-7" 
"/$lang/blog/2019/running-a-guix-xfce-desktop-on-centos-7/")
-   (redirect "/blog/2019/spreading-the-news" 
"/$lang/blog/2019/spreading-the-news/")
-   (redirect "/blog/2019/substitutes-are-now-available-as-lzip" 
"/$lang/blog/2019/substitutes-are-now-available-as-lzip/")
-   (redirect "/blog/2019/towards-guix-for-devops" 
"/$lang/blog/2019/towards-guix-for-devops/")
-   (redirect "/blog/2020/a-hello-world-virtual-machine-running-the-hurd" 
"/$lang/blog/2020/a-hello-world-virtual-machine-running-the-hurd/")
-   (redirect "/blog/2020/deprecating-support-for-the-linux-kernel" 
"/$lang/blog/2020/deprecating-support-for-the-linux-kernel/")
-   (redirect "/blog/2020/gnu-guix-1.1.0-released" 
"/$lang/blog/2020/gnu-guix-1.1.0-released/")
-   (redirect "/blog/2020/gnu-guix-maintainer-collective-update" 
"/$lang/blog/2020/gnu-guix-maintainer-collective-update/")
-   (redirect "/blog/2020/gnu-shepherd-user-services" 
"/$lang/blog/2020/gnu-shepherd-user-services/")
-   (redirect "/blog/2020/grafts-continued" 
"/$lang/blog/2020/grafts-continued/")
-   (redirect 
"/blog/2020/gsoc-2020-and-outreachy-may-2020-to-august-2020-status-report-ii" 
"/$lang/blog/2020/gsoc-2020-and-outreachy-may-2020-to-august-2020-status-report-ii/")
-   (redirect "/blog/2020/guile-3-and-guix" 
"/$lang/blog/2020/guile-3-and-guix/")
-   (redirect "/blog/2020/guix-further-reduces-bootstrap-seed-to-25" 
"/$lang/blog/2020/guix-further-reduces-bootstrap-seed-to-25/")
-   (redirect "/blog/2020/guix-welcomes-outreachy-and-gsoc-interns" 
"/$lang/blog/2020/guix-welcomes-outreachy-and-gsoc-interns/")
-   (redirect "/blog/2020/join-gnu-guix-through-outreachy" 
"/$lang/blog/2020/join-gnu-guix-through-outreachy/")
-   (redirect "/blog/2020/meet-guix-at-fosdem-2020" 
"/$lang/blog/2020/meet-guix-at-fosdem-2020/")
-   (redirect "/blog/2020/outreachy-may-2020-to-august-2020-status-report-i" 
"/$lang/blog/2020/outreachy-may-2020-to-august-2020-status-report-i/")
-   (redirect "/blog/2020/reproducible-computations-with-guix" 
"/$lang/blog/2020/reproducible-computations-with-guix/")
-   (redirect "/blog/2020/securing-updates" 
"/$lang/blog/2020/securing-updates/")
-   (redirect "/blog/page/1" "/$lang/blog/page/1/")
-   (redirect "/blog/page/2" "/$lang/blog/page/2/")
-   (redirect "/blog/page/3" "/$lang/blog/page/3/")
-   (redirect "/blog/page/4" "/$lang/blog/page/4/")
-   (redirect "/blog/page/5" "/$lang/blog/page/5/")
-   (redirect "/blog/tags/arm" "/$lang/blog/tags/arm/")
-   (redirect "/blog/tags/arm/page/1" "/$lang/blog/tags/arm/page/1/")
-   (redirect "/blog/tags/bioinformatics" "/$lang/blog/tags/bioinformatics/")
-   (redirect "/blog/tags/bioinformatics/page/1" 
"/$lang/blog/tags/bioinformatics/page/1/")
-   (redirect "/blog/tags/bootstrapping" "/$lang/blog/tags/bootstrapping/")
-   (redirect "/blog/tags/bootstrapping/page/1" 
"/$lang/blog/tags/bootstrapping/page/1/")
-   (redirect "/blog/tags/build-farm" "/$lang/blog/tags/build-farm/")
-   (redirect "/blog/tags/build-farm/page/1" 
"/$lang/blog/tags/build-farm/page/1/")
-   (redirect "/blog/tags/community" "/$lang/blog/tags/community/")
-   (redirect "/blog/tags/community/page/1" 
"/$lang/blog/tags/community/page/1/")
-   (redirect "/blog/tags/containers" "/$lang/blog/tags/containers/")
-   (redirect "/blog/tags/containers/page/1" 
"/$lang/blog/tags/containers/page/1/")
-   (redirect "/blog/tags/continuous-integration" 
"/$lang/blog/tags/continuous-integration/")
-   (redirect "/blog/tags/continuous-integration/page/1" 
"/$lang/blog/tags/continuous-integration/page/1/")
-   (redirect "/blog/tags/cookbook" "/$lang/blog/tags/cookbook/")
-   (redirect "/blog/tags/cookbook/page/1" "/$lang/blog/tags/cookbook/page/1/")
-   (redirect "/blog/tags/cross-compilation" 
"/$lang/blog/tags/cross-compilation/")
-   (redirect "/blog/tags/cross-compilation/page/1" 
"/$lang/blog/tags/cross-compilation/page/1/")
-   (redirect "/blog/tags/customization" "/$lang/blog/tags/customization/")
-   (redirect "/blog/tags/customization/page/1" 
"/$lang/blog/tags/customization/page/1/")
-   (redirect "/blog/tags/desktop-environments" 
"/$lang/blog/tags/desktop-environments/")
-   (redirect "/blog/tags/desktop-environments/page/1" 
"/$lang/blog/tags/desktop-environments/page/1/")
-   (redirect "/blog/tags/documentation" "/$lang/blog/tags/documentation/")
-   (redirect "/blog/tags/documentation/page/1" 
"/$lang/blog/tags/documentation/page/1/")
-   (redirect "/blog/tags/federation" "/$lang/blog/tags/federation/")
-   (redirect "/blog/tags/federation/page/1" 
"/$lang/blog/tags/federation/page/1/")
-   (redirect "/blog/tags/foreign-distribution" 
"/$lang/blog/tags/foreign-distribution/")
-   (redirect "/blog/tags/foreign-distribution/page/1" 
"/$lang/blog/tags/foreign-distribution/page/1/")
-   (redirect "/blog/tags/fosdem" "/$lang/blog/tags/fosdem/")
-   (redirect "/blog/tags/fosdem/page/1" "/$lang/blog/tags/fosdem/page/1/")
-   (redirect "/blog/tags/functional-package-management" 
"/$lang/blog/tags/functional-package-management/")
-   (redirect "/blog/tags/functional-package-management/page/1" 
"/$lang/blog/tags/functional-package-management/page/1/")
-   (redirect "/blog/tags/functional-programming" 
"/$lang/blog/tags/functional-programming/")
-   (redirect "/blog/tags/functional-programming/page/1" 
"/$lang/blog/tags/functional-programming/page/1/")
-   (redirect "/blog/tags/fundraising" "/$lang/blog/tags/fundraising/")
-   (redirect "/blog/tags/fundraising/page/1" 
"/$lang/blog/tags/fundraising/page/1/")
-   (redirect "/blog/tags/gnuhurd" "/$lang/blog/tags/gnuhurd/")
-   (redirect "/blog/tags/gnuhurd/page/1" "/$lang/blog/tags/gnuhurd/page/1/")
-   (redirect "/blog/tags/gsoc" "/$lang/blog/tags/gsoc/")
-   (redirect "/blog/tags/gsoc/page/1" "/$lang/blog/tags/gsoc/page/1/")
-   (redirect "/blog/tags/guix-days" "/$lang/blog/tags/guix-days/")
-   (redirect "/blog/tags/guix-days/page/1" 
"/$lang/blog/tags/guix-days/page/1/")
-   (redirect "/blog/tags/guix-hackathon" "/$lang/blog/tags/guix-hackathon/")
-   (redirect "/blog/tags/guix-hackathon/page/1" 
"/$lang/blog/tags/guix-hackathon/page/1/")
-   (redirect "/blog/tags/high-performance-computing" 
"/$lang/blog/tags/high-performance-computing/")
-   (redirect "/blog/tags/high-performance-computing/page/1" 
"/$lang/blog/tags/high-performance-computing/page/1/")
-   (redirect "/blog/tags/init-system" "/$lang/blog/tags/init-system/")
-   (redirect "/blog/tags/init-system/page/1" 
"/$lang/blog/tags/init-system/page/1/")
-   (redirect "/blog/tags/interviews" "/$lang/blog/tags/interviews/")
-   (redirect "/blog/tags/interviews/page/1" 
"/$lang/blog/tags/interviews/page/1/")
-   (redirect "/blog/tags/libreboot" "/$lang/blog/tags/libreboot/")
-   (redirect "/blog/tags/libreboot/page/1" 
"/$lang/blog/tags/libreboot/page/1/")
-   (redirect "/blog/tags/linux" "/$lang/blog/tags/linux/")
-   (redirect "/blog/tags/linux/page/1" "/$lang/blog/tags/linux/page/1/")
-   (redirect "/blog/tags/mips" "/$lang/blog/tags/mips/")
-   (redirect "/blog/tags/mips/page/1" "/$lang/blog/tags/mips/page/1/")
-   (redirect "/blog/tags/outreachy" "/$lang/blog/tags/outreachy/")
-   (redirect "/blog/tags/outreachy/page/1" 
"/$lang/blog/tags/outreachy/page/1/")
-   (redirect "/blog/tags/papers" "/$lang/blog/tags/papers/")
-   (redirect "/blog/tags/papers/page/1" "/$lang/blog/tags/papers/page/1/")
-   (redirect "/blog/tags/programming-interfaces" 
"/$lang/blog/tags/programming-interfaces/")
-   (redirect "/blog/tags/programming-interfaces/page/1" 
"/$lang/blog/tags/programming-interfaces/page/1/")
-   (redirect "/blog/tags/releases" "/$lang/blog/tags/releases/")
-   (redirect "/blog/tags/releases/page/1" "/$lang/blog/tags/releases/page/1/")
-   (redirect "/blog/tags/reproducibility" "/$lang/blog/tags/reproducibility/")
-   (redirect "/blog/tags/reproducibility/page/1" 
"/$lang/blog/tags/reproducibility/page/1/")
-   (redirect "/blog/tags/reproducible-builds" 
"/$lang/blog/tags/reproducible-builds/")
-   (redirect "/blog/tags/reproducible-builds/page/1" 
"/$lang/blog/tags/reproducible-builds/page/1/")
-   (redirect "/blog/tags/research" "/$lang/blog/tags/research/")
-   (redirect "/blog/tags/research/page/1" "/$lang/blog/tags/research/page/1/")
-   (redirect "/blog/tags/scheme-api" "/$lang/blog/tags/scheme-api/")
-   (redirect "/blog/tags/scheme-api/page/1" 
"/$lang/blog/tags/scheme-api/page/1/")
-   (redirect "/blog/tags/security" "/$lang/blog/tags/security/")
-   (redirect "/blog/tags/security/page/1" "/$lang/blog/tags/security/page/1/")
-   (redirect "/blog/tags/security-advisory" 
"/$lang/blog/tags/security-advisory/")
-   (redirect "/blog/tags/security-advisory/page/1" 
"/$lang/blog/tags/security-advisory/page/1/")
-   (redirect "/blog/tags/security-updates" 
"/$lang/blog/tags/security-updates/")
-   (redirect "/blog/tags/security-updates/page/1" 
"/$lang/blog/tags/security-updates/page/1/")
-   (redirect "/blog/tags/shepherd" "/$lang/blog/tags/shepherd/")
-   (redirect "/blog/tags/shepherd/page/1" "/$lang/blog/tags/shepherd/page/1/")
-   (redirect "/blog/tags/software-development" 
"/$lang/blog/tags/software-development/")
-   (redirect "/blog/tags/software-development/page/1" 
"/$lang/blog/tags/software-development/page/1/")
-   (redirect "/blog/tags/system-services" "/$lang/blog/tags/system-services/")
-   (redirect "/blog/tags/system-services/page/1" 
"/$lang/blog/tags/system-services/page/1/")
-   (redirect "/blog/tags/system-tests" "/$lang/blog/tags/system-tests/")
-   (redirect "/blog/tags/system-tests/page/1" 
"/$lang/blog/tags/system-tests/page/1/")
-   (redirect "/blog/tags/talks" "/$lang/blog/tags/talks/")
-   (redirect "/blog/tags/talks/page/1" "/$lang/blog/tags/talks/page/1/")
-   (redirect "/blog/tags/talks/page/2" "/$lang/blog/tags/talks/page/2/")
-   (redirect "/blog/tags/transactional-upgrades" 
"/$lang/blog/tags/transactional-upgrades/")
-   (redirect "/blog/tags/transactional-upgrades/page/1" 
"/$lang/blog/tags/transactional-upgrades/page/1/")
-   (redirect "/blog/tags/trust" "/$lang/blog/tags/trust/")
-   (redirect "/blog/tags/trust/page/1" "/$lang/blog/tags/trust/page/1/")
-   (redirect "/blog/tags/user-interfaces" "/$lang/blog/tags/user-interfaces/")
-   (redirect "/blog/tags/user-interfaces/page/1" 
"/$lang/blog/tags/user-interfaces/page/1/")
-   (redirect "/blog/tags/virtual-machine-images" 
"/$lang/blog/tags/virtual-machine-images/")
-   (redirect "/blog/tags/virtual-machine-images/page/1" 
"/$lang/blog/tags/virtual-machine-images/page/1/")
-   (redirect "/blog/tags/xfce" "/$lang/blog/tags/xfce/")
-   (redirect "/blog/tags/xfce/page/1" "/$lang/blog/tags/xfce/page/1/")
-   (redirect "/contact" "/$lang/contact/")
-   (redirect "/contact/irc" "/$lang/contact/irc/")
-   (redirect "/contribute" "/$lang/contribute/")
-   (redirect "/donate" "/$lang/donate/")
-   (redirect "/machines" "/$lang/donate/")
-   (redirect "/download" "/$lang/download/")
-   (redirect "/download/latest" "/$lang/download/latest/")
-   (redirect "/graphics" "/$lang/graphics/")
-   (redirect "/help" "/$lang/help/")
-   (redirect "/menu" "/$lang/menu/")
-   (redirect "/packages" "/$lang/packages/")
-   (redirect "/screenshots" "/$lang/screenshots/")
-   (redirect "/screenshots/enlightenment" "/$lang/screenshots/enlightenment/")
-   (redirect "/screenshots/gnome" "/$lang/screenshots/gnome/")
-   (redirect "/screenshots/slim" "/$lang/screenshots/slim/")
-   (redirect "/screenshots/sway" "/$lang/screenshots/sway/")
-   (redirect "/screenshots/virtual-machine" 
"/$lang/screenshots/virtual-machine/")
-   (redirect "/screenshots/xfce" "/$lang/screenshots/xfce/")
-   (redirect "/security" "/$lang/security/")
-   (redirect "/videos" "/$lang/videos/")))
-
-(define languages-to-accept
-  ;; List of languages for redirection; see 'accept-languages' further
-  ;; below.
-  '(("en")
-    ("de")
-    ("eo")
-    ("es")
-    ("fr")
-    ("ko")
-    ("ru")
-    ("sk")
-    ("tr")
-    ("zh-CN" "zh" "zh-Hans" "zh-Hans-CN")
-    ("zh-TW" "zh-Hant" "zh-Hant-TW")))
-
-(define (guix.gnu.org-redirects-for-each-language)
-  ;; These old URL request paths existed in many forms; without /LANG
-  ;; in front and with /LANG in front for each language.  Redirect
-  ;; each of them.
-  (define redirections
-    (list
-     (cons "/videos/everyday-use-of-gnu-guix,-part-one" 
"/videos/2020/everyday-use-of-gnu-guix-part-one/")
-     (cons "/videos/everyday-use-of-gnu-guix,-part-two" 
"/videos/2020/everyday-use-of-gnu-guix-part-two/")
-     (cons "/videos/system-graphical-installer" 
"/videos/2020/system-graphical-installer/")
-     (cons "/videos/asking-for-help" "/videos/2020/asking-for-help/")
-     (cons "/videos/installation-from-script" 
"/videos/2020/installation-from-script/")
-     (cons "/videos/packaging,-part-one" "/videos/2020/packaging-part-one/")
-     (cons "/videos/packaging,-part-two" "/videos/2020/packaging-part-two/")
-     (cons "/videos/packaging,-part-three" 
"/videos/2020/packaging-part-three/")))
-
-  (define (redirect-directory old new)
-    ;; Match nginx' behavior that request URLs with suffix "", "/"
-    ;; "/index.html" lead to the same file.  The suffix "/" is not taken
-    ;; care of here because it already gets normalized by nginx location
-    ;; handling.  The URLs in 'guix.gnu.org-redirect-locations' do not
-    ;; need this treatment, because they get an /index.html suffix
-    ;; through rewriting.
-    (let ((old-with-slashes-trimmed (string-trim-right old #\/)))
-      (list
-       (redirect old-with-slashes-trimmed new)
-       (redirect (string-append old-with-slashes-trimmed "/index.html") new))))
-
-  (define (guix.gnu.org-redirect-locations-for-lang lang)
-    (define (redirect-lang old new)
-      (redirect-directory (string-append "/" lang old)
-                          (string-append "/" lang new)))
-    (append-map redirect-lang (map car redirections) (map cdr redirections)))
-
-  (append
-   ;; Now all needed redirections are:
-   ;;
-   ;; 1) those without /LANG/ in front get redirected to /$lang/
-   (append-map redirect-directory
-               (map car redirections) ;old URLs without /LANG
-               ;; new URLs with /$lang prepended:
-               (map (compose (lambda (new-without-lang)
-                               (string-append "/$lang" new-without-lang))
-                             cdr)
-                    redirections))
-   ;; 2) those with /LANG/ in front get redirected to the same /LANG/
-   (append-map guix.gnu.org-redirect-locations-for-lang
-               (map car languages-to-accept))))
-
-(define guix.gnu.org-other-locations
-  (list
-   (nginx-location-configuration
-    (uri "/guix-videos")
-    (body (list "alias /srv/videos;")))
-
-   (nginx-location-configuration
-    (uri "/audio")
-    (body (list "alias /srv/audio;")))
-
-   (nginx-location-configuration
-    (uri "^~ /cuirass/manual")
-    (body (list "alias /srv/cuirass-manual;")))
-
-   (nginx-location-configuration
-    (uri "^~ /cuirass/releases")
-    (body (list "alias /srv/cuirass-releases;")))
-
-   ;; Let browsers cache files under /static for a while.
-   ;; XXX: This is really a hack to work around the fact that we can't have
-   ;; 'If-Modified-Since' because timestamps are zeroed.
-   (nginx-location-configuration
-    (uri "/static")
-    (body (list "expires 1d;"
-                "alias /srv/guix.gnu.org/static;")))
-
-   ;; These rules take precedence over the '.pdf' and '.html' rules below.
-   (nginx-location-configuration
-    (uri "~ /manual/devel/(.*)$")
-    (body (list "expires 4h;"
-                "alias /srv/guix-manual-devel/$1;")))
-   (nginx-location-configuration
-    (uri "~ /manual/(.*)$")
-    (body (list "expires 1d;"
-                "alias /srv/guix-manual/$1;")))
-   (nginx-location-configuration
-    (uri "~ /cookbook/(.*)$")
-    (body (list "expires 4h;"
-                "alias /srv/guix-cookbook/$1;")))
-   (nginx-location-configuration
-    (uri "~ \\.pdf$")                             ;*.pdf at the top level
-    (body (list "root /srv/guix-pdfs;")))
-
-   (git-http-nginx-location-configuration
-    (git-http-configuration))
-
-   ;; For Hurd bootstrap binaries.
-   (nginx-location-configuration
-    (uri "/guix")
-    (body (list "root /var/www;")))
-
-   (nginx-location-configuration
-    (uri "~ (.html|.htm)$")
-    (body (list "try_files $uri /$lang/$uri /$lang/$uri/index.html =404;")))
-
-   (nginx-location-configuration                  ;certbot
-    (uri "/.well-known")
-    (body (list "root /var/www;")))))
-
-(define guix.gnu.org-locations
-  (append guix.gnu.org-redirect-locations
-          (guix.gnu.org-redirects-for-each-language)
-          guix.gnu.org-other-locations))
-
 (define %publish-url "http://localhost:3000";)
 
 (define %berlin-servers
@@ -947,28 +295,7 @@ PUBLISH-URL."
      (list "gzip_static always; gunzip on;\n"
            "access_log /var/log/nginx/disarchive.access.log;")))
 
-   (nginx-server-configuration
-    (listen '("443 ssl"))
-    (server-name '("guix.gnu.org"))
-    (ssl-certificate (le "guix.gnu.org"))
-    (ssl-certificate-key (le "guix.gnu.org" 'key))
-    (root "/srv/guix.gnu.org")
-    (locations guix.gnu.org-locations)
-    (raw-content
-     (append
-      %tls-settings
-      (list
-       "add_header Content-Security-Policy \"frame-ancestors 'none'\";"
-
-       ;; TODO This works around NGinx using the epoch for the
-       ;; Last-Modified date, as well as the etag.
-       ;; See http://issues.guix.gnu.org/37207
-       "add_header Last-Modified \"\";"
-       "if_modified_since off;"
-       "etag off;"
-
-       "rewrite (.*)/$ $1/index.html;"
-       "access_log /var/log/nginx/guix-gnu-org.https.access.log;"))))
+   guix.gnu.org-nginx-server
 
    (nginx-server-configuration
     (listen '("443 ssl"))
@@ -1074,33 +401,12 @@ PUBLISH-URL."
        (uri "~ /(.*)")
        (body (list "return 301 $scheme://guixwl.org/$1;"))))))))
 
-(define (accept-languages language-lists)
-  "Returns nginx configuration code to set up the $lang variable
-according to the Accept-Language header in the HTTP request.  The
-requesting user agent will be served the files at /$lang/some/url.
-Each list in LANGUAGE-LISTS starts with the $lang and is followed by
-synonymous IETF language tags that should be mapped to the same $lang."
-  (define (language-mappings language-list)
-    (define (language-mapping language)
-      (string-join (list "    "  language (car language-list) ";")))
-    (string-join (map language-mapping language-list) "\n"))
-
-  (let ((directives
-         `(,(string-join
-             `("set_from_accept_language $lang_unmapped"
-               ,@(map string-join language-lists)
-               ";"))
-           "map $lang_unmapped $lang {"
-           ,@(map language-mappings language-lists)
-           "}")))
-    (string-join directives "\n")))
-
 (define %extra-content
   (list
    "default_type  application/octet-stream;"
    "sendfile        on;"
 
-   (accept-languages languages-to-accept)
+   (accept-languages)
 
    ;; Maximum chunk size to send.  Partly this is a workaround for
    ;; <http://bugs.gnu.org/19939>, but also the nginx docs mention that



reply via email to

[Prev in Thread] Current Thread [Next in Thread]