;; Nginx configuration for ci.guix.gnu.org ;; Copyright © 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès ;; Copyright © 2017, 2018, 2019, 2020, 2021 Ricardo Wurmus ;; Copyright © 2020 Christopher Baines ;; Copyright © 2020, 2021 Florian Pelz ;; Copyright © 2020 Tobias Geerinckx-Rice ;; Copyright © 2021 Mathieu Othacehe ;; 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 . "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., ;; . (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" ;; "~[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 ;; , but also the nginx docs mention that ;; "Without the limit, one fast connection may seize the worker ;; process entirely." ;; "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"))))