maintenance/hydra/nginx/berlin.scm

1190 lines
73 KiB
Scheme
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;; Nginx configuration for ci.guix.gnu.org
;; Copyright © 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
;; Copyright © 2017, 2018, 2019, 2020, 2021 Ricardo Wurmus <rekado@elephly.net>
;; Copyright © 2020 Christopher Baines <mail@cbaines.net>
;; Copyright © 2020, 2021 Florian Pelz <pelzflorian@pelzflorian.de>
;; Copyright © 2020 Tobias Geerinckx-Rice <me@tobias.gr>
;; 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* (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-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 2s;"
"proxy_read_timeout 2s;"
"proxy_send_timeout 2s;"
;; '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;")))))
(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."
(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;")))
(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;")))
(nginx-location-configuration ;certbot
(uri "/.well-known")
(body (list "root /var/www;")))
(nginx-location-configuration
(uri "/berlin.guixsd.org-export.pub")
(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
(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
(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"))
(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"))))