;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2012 Nikita Karetnikov ;;; Copyright © 2013, 2017, 2020, 2021 Ludovic Courtès ;;; Copyright © 2013, 2015 Andreas Enge ;;; Copyright © 2015, 2016, 2017, 2018, 2019, 2021 Efraim Flashner ;;; Copyright © 2015, 2017 Leo Famulari ;;; Copyright © 2015, 2017 Cyril Roelandt ;;; Copyright © 2016 Sou Bunnbu ;;; Copyright © 2016 Hartmut Goebel ;;; Copyright © 2016 Danny Milosavljevic ;;; Copyright © 2016, 2020 Marius Bakke ;;; Copyright © 2016, 2017, 2018, 2020 Tobias Geerinckx-Rice ;;; Copyright © 2017 Ben Woodcroft ;;; Copyright © 2017 Nikita ;;; Copyright © 2017 Julien Lepiller ;;; Copyright © 2018 Alex Vong ;;; Copyright © 2019 Kyle Meyer ;;; Copyright © 2019 Pierre Langlois ;;; Copyright © 2020 Lars-Dominik Braun ;;; Copyright © 2020 Tanguy Le Carrour ;;; Copyright © 2021 Ryan Prior ;;; Copyright © 2021 Foo Chuan Wei ;;; Copyright © 2022 Pradana AUMARS ;;; Copyright © 2023 Sharlatan Hellseher ;;; ;;; This file is part of GNU Guix. ;;; ;;; GNU Guix is free software; you can redistribute it and/or modify it ;;; under the terms of the GNU General Public License as published by ;;; the Free Software Foundation; either version 3 of the License, or (at ;;; your option) any later version. ;;; ;;; GNU Guix is distributed in the hope that it will be useful, but ;;; WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNES;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2015 David Thompson <davet@gnu.org> ;;; Copyright © 2015-2023 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2016 Nikita <nikita@n0.is> ;;; Copyright © 2016, 2017, 2018 Julien Lepiller <julien@lepiller.eu> ;;; Copyright © 2017, 2018, 2019 Christopher Baines <mail@cbaines.net> ;;; Copyright © 2017 nee <nee-git@hidamari.blue> ;;; Copyright © 2017, 2018 Clément Lassieur <clement@lassieur.org> ;;; Copyright © 2018 Pierre-Antoine Rouby <pierre-antoine.rouby@inria.fr> ;;; Copyright © 2018 Marius Bakke <mbakke@fastmail.com> ;;; Copyright © 2019, 2020 Florian Pelz <pelzflorian@pelzflorian.de> ;;; Copyright © 2020, 2022 Ricardo Wurmus <rekado@elephly.net> ;;; Copyright © 2020 Tobias Geerinckx-Rice <me@tobias.gr> ;;; Copyright © 2020 Arun Isaac <arunisaac@systemreboot.net> ;;; Copyright © 2020 Oleg Pykhalov <go.wigust@gmail.com> ;;; Copyright © 2020, 2021 Alexandru-Sergiu Marton <brown121407@posteo.ro> ;;; Copyright © 2022 Simen Endsjø <simendsjo@gmail.com> ;;; Copyright © 2023 Bruno Victal <mirai@makinata.eu> ;;; Copyright © 2023 Miguel Ángel Moreno <mail@migalmoreno.com> ;;; Copyright © 2024 Wojtek Kosior <koszko@koszko.org> ;;; Additions and modifications by Wojtek Kosior are additionally ;;; dual-licensed under the Creative Commons Zero v1.0. ;;; ;;; This file is part of GNU Guix. ;;; ;;; GNU Guix is free software; you can redistribute it and/or modify it ;;; under the terms of the GNU General Public License as published by ;;; the Free Software Foundation; either version 3 of the License, or (at ;;; your option) any later version. ;;; ;;; GNU Guix is distributed in the hope that it will be useful, but ;;; WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;; GNU General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. (define-module (gnu services web) #:use-module (gnu services) #:use-module (gnu services shepherd) #:use-module (gnu services admin) #:use-module (gnu services configuration) #:use-module (gnu services getmail) #:use-module (gnu services mail) #:use-module (gnu system pam) #:use-module (gnu system shadow) #:use-module (gnu packages admin) #:use-module (gnu packages base) #:use-module (gnu packages databases) #:use-module ((gnu packages linux) #:select (util-linux)) #:use-module (gnu packages web) #:use-module (gnu packages patchutils) #:use-module (gnu packages php) #:use-module (gnu packages python) #:use-module (gnu packages python-web) #:use-module (gnu packages gnupg) #:use-module (gnu packages guile) #:use-module (gnu packages logging) #:use-module (gnu packages mail) #:use-module (gnu packages rust-apps) #:autoload (guix i18n) (G_) #:use-module (guix diagnostics) #:use-module (guix packages) #:use-module (guix records) #:use-module (guix modules) #:use-module (guix utils) #:use-module (guix gexp) #:use-module ((guix store) #:select (text-file)) #:use-module ((guix utils) #:select (version-major)) #:use-module ((guix packages) #:select (package-version)) #:use-module (srfi srfi-1) #:use-module (srfi srfi-9) #:use-module (srfi srfi-34) #:use-module (ice-9 match) #:use-module (ice-9 format) #:export (httpd-configuration httpd-configuration? httpd-configuration-package httpd-configuration-pid-file httpd-configuration-config httpd-virtualhost httpd-virtualhost? httpd-virtualhost-addresses-and-ports httpd-virtualhost-contents httpd-config-file httpd-config-file? httpd-config-file-modules httpd-config-file-server-root httpd-config-file-server-name httpd-config-file-listen httpd-config-file-pid-file httpd-config-file-error-log httpd-config-file-user httpd-config-file-group httpd-module httpd-module? %default-httpd-modules httpd-service-type nginx-configuration nginx-configuration? nginx-configuration-nginx nginx-configuration-shepherd-requirement nginx-configuration-log-directory nginx-configuration-log-level nginx-configuration-run-directory nginx-configuration-server-blocks nginx-configuration-upstream-blocks nginx-configuration-server-names-hash-bucket-size nginx-configuration-server-names-hash-bucket-max-size nginx-configuration-modules nginx-configuration-global-directives nginx-configuration-extra-content nginx-configuration-file nginx-server-configuration nginx-server-configuration? nginx-server-configuration-listen nginx-server-configuration-server-name nginx-server-configuration-root nginx-server-configuration-locations nginx-server-configuration-index nginx-server-configuration-ssl-certificate nginx-server-configuration-ssl-certificate-key nginx-server-configuration-server-tokens? nginx-server-configuration-raw-content nginx-upstream-configuration nginx-upstream-configuration? nginx-upstream-configuration-name nginx-upstream-configuration-servers nginx-upstream-configuration-extra-content nginx-location-configuration nginx-location-configuration? nginx-location-configuration-uri nginx-location-configuration-body nginx-named-location-configuration nginx-named-location-configuration? nginx-named-location-configuration-name nginx-named-location-configuration-body nginx-service nginx-service-type fcgiwrap-configuration fcgiwrap-configuration? fcgiwrap-service-type php-fpm-configuration make-php-fpm-configuration php-fpm-configuration? php-fpm-configuration-php php-fpm-configuration-socket php-fpm-configuration-user php-fpm-configuration-group php-fpm-configuration-socket-user php-fpm-configuration-socket-group php-fpm-configuration-pid-file php-fpm-configuration-log-file php-fpm-configuration-process-manager php-fpm-configuration-display-errors php-fpm-configuration-timezone php-fpm-configuration-workers-log-file php-fpm-configuration-file php-fpm-configuration-php-ini-file php-fpm-dynamic-process-manager-configuration make-php-fpm-dynamic-process-manager-configuration php-fpm-dynamic-process-manager-configuration? php-fpm-dynamic-process-manager-configuration-max-children php-fpm-dynamic-process-manager-configuration-start-servers php-fpm-dynamic-process-manager-configuration-min-spare-servers php-fpm-dynamic-process-manager-configuration-max-spare-servers php-fpm-static-process-manager-configuration make-php-fpm-static-process-manager-configuration php-fpm-static-process-manager-configuration? php-fpm-static-process-manager-configuration-max-children php-fpm-on-demand-process-manager-configuration make-php-fpm-on-demand-process-manager-configuration php-fpm-on-demand-process-manager-configuration? php-fpm-on-demand-process-manager-configuration-max-children php-fpm-on-demand-process-manager-configuration-process-idle-timeout php-fpm-service-type nginx-php-location cat-avatar-generator-service hpcguix-web-configuration hpcguix-web-configuration? hpcguix-web-service-type tailon-configuration-file tailon-configuration-file? tailon-configuration-file-files tailon-configuration-file-bind tailon-configuration-file-relative-root tailon-configuration-file-allow-transfers? tailon-configuration-file-follow-names? tailon-configuration-file-tail-lines tailon-configuration-file-allowed-commands tailon-configuration-file-debug? tailon-configuration-file-http-auth tailon-configuration-file-users tailon-configuration tailon-configuration? tailon-configuration-config-file tailon-configuration-package tailon-service-type anonip-configuration anonip-configuration? anonip-configuration-anonip anonip-configuration-input anonip-configuration-output anonip-configuration-skip-private? anonip-configuration-column anonip-configuration-replacement anonip-configuration-ipv4mask anonip-configuration-ipv6mask anonip-configuration-increment anonip-configuration-delimiter anonip-configuration-regex anonip-service-type varnish-configuration varnish-configuration? varnish-configuration-package varnish-configuration-name varnish-configuration-backend varnish-configuration-vcl varnish-configuration-listen varnish-configuration-storage varnish-configuration-parameters varnish-configuration-extra-options varnish-service-type whoogle-service-type whoogle-configuration whoogle-configuration-package whoogle-configuration-host whoogle-configuration-port whoogle-configuration-environment-variables epicyon-service-type epicyon-configuration epicyon-configuration? epicyon-configuration-package epicyon-configuration-port epicyon-configuration-real-port epicyon-configuration-domain epicyon-configuration-registration-open? epicyon-configuration-log-login-failures? patchwork-database-configuration patchwork-database-configuration? patchwork-database-configuration-engine patchwork-database-configuration-name patchwork-database-configuration-user patchwork-database-configuration-password patchwork-database-configuration-host patchwork-database-configuration-port patchwork-settings-module patchwork-settings-module? patchwork-settings-module-database-configuration patchwork-settings-module-secret-key patchwork-settings-module-allowed-hosts patchwork-settings-module-default-from-email patchwork-settings-module-static-url patchwork-settings-module-admins patchwork-settings-module-debug? patchwork-settings-module-enable-rest-api? patchwork-settings-module-enable-xmlrpc? patchwork-settings-module-force-https-links? patchwork-settings-module-extra-settings patchwork-configuration patchwork-configuration? patchwork-configuration-patchwork patchwork-configuration-settings-module patchwork-configuration-domain patchwork-virtualhost patchwork-service-type mumi-configuration mumi-configuration? mumi-configuration-mumi mumi-configuration-mailer? mumi-configuration-sender mumi-configuration-smtp mumi-service-type gmnisrv-configuration gmnisrv-configuration? gmnisrv-configuration-package gmnisrv-configuration-config-file gmnisrv-service-type agate-configuration agate-configuration? agate-configuration-package agate-configuration-content agate-configuration-certs agate-configuration-addr agate-configuration-hostname agate-configuration-lang agate-configuration-only-tls13 agate-configuration-serve-secret agate-configuration-central-conf agate-configuration-ed25519 agate-configuration-skip-port-check agate-configuration-log-ip agate-configuration-user agate-configuration-group agate-configuration-log-file agate-service-type)) ;;; Commentary: ;;; ;;; Web services. ;;; ;;; Code: (define-record-type* <httpd-module> httpd-module make-httpd-module httpd-module? (name httpd-load-module-name) (file httpd-load-module-file)) ;; Default modules for the httpd-service-type, taken from etc/httpd/httpd.conf ;; file in the httpd package. (define %default-httpd-modules (map (match-lambda ((name file) (httpd-module (name name) (file file)))) '(("authn_file_module" "modules/mod_authn_file.so") ("authn_core_module" "modules/mod_authn_core.so") ("authz_host_module" "modules/mod_authz_host.so") ("authz_groupfile_module" "modules/mod_authz_groupfile.so") ("authz_user_module" "modules/mod_authz_user.so") ("authz_core_module" "modules/mod_authz_core.so") ("access_compat_module" "modules/mod_access_compat.so") ("auth_basic_module" "modules/mod_auth_basic.so") ("reqtimeout_module" "modules/mod_reqtimeout.so") ("filter_module" "modules/mod_filter.so") ("mime_module" "modules/mod_mime.so") ("log_config_module" "modules/mod_log_config.so") ("env_module" "modules/mod_env.so") ("headers_module" "modules/mod_headers.so") ("setenvif_module" "modules/mod_setenvif.so") ("version_module" "modules/mod_version.so") ("unixd_module" "modules/mod_unixd.so") ("status_module" "modules/mod_status.so") ("autoindex_module" "modules/mod_autoindex.so") ("dir_module" "modules/mod_dir.so") ("alias_module" "modules/mod_alias.so")))) (define-record-type* <httpd-config-file> httpd-config-file make-httpd-config-file httpd-config-file? (modules httpd-config-file-modules (default %default-httpd-modules)) (server-root httpd-config-file-server-root (default httpd)) (server-name httpd-config-file-server-name (default #f)) (document-root httpd-config-file-document-root (default "/srv/http")) (listen httpd-config-file-listen (default '("80"))) (pid-file httpd-config-file-pid-file (default "/var/run/httpd")) (error-log httpd-config-file-error-log (default "/var/log/httpd/error_log")) (user httpd-config-file-user (default "httpd")) (group httpd-config-file-group (default "httpd")) (extra-config httpd-config-file-extra-config (default (list "TypesConfig etc/httpd/mime.types")))) (define-gexp-compiler (httpd-config-file-compiler (file <httpd-config-file>) system target) (match file (($ <httpd-config-file> load-modules server-root server-name document-root listen pid-file error-log user group extra-config) (gexp->derivation "httpd.conf" #~(call-with-output-file (ungexp output "out") (lambda (port) (display (string-append (ungexp-splicing `(,@(append-map (match-lambda (($ <httpd-module> name module) `("LoadModule " ,name " " ,module "\n"))) load-modules) ,@`("ServerRoot " ,server-root "\n") ,@(if server-name `("ServerName " ,server-name "\n") '()) ,@`("DocumentRoot " ,document-root "\n") ,@(append-map (lambda (listen-value) `("Listen " ,listen-value "\n")) listen) ,@(if pid-file `("Pidfile " ,pid-file "\n") '()) ,@(if error-log `("ErrorLog " ,error-log "\n") '()) ,@(if user `("User " ,user "\n") '()) ,@(if group `("Group " ,group "\n") '()) "\n\n" ,@extra-config))) port))) #:local-build? #t)))) (define-record-type <httpd-virtualhost> (httpd-virtualhost addresses-and-ports contents) httpd-virtualhost? (addresses-and-ports httpd-virtualhost-addresses-and-ports) (contents httpd-virtualhost-contents)) (define-record-type* <httpd-configuration> httpd-configuration make-httpd-configuration httpd-configuration? (package httpd-configuration-package (default httpd)) (pid-file httpd-configuration-pid-file (default "/var/run/httpd")) (config httpd-configuration-config (default (httpd-config-file)))) (define %httpd-accounts (list (user-group (name "httpd") (system? #t)) (user-account (name "httpd") (group "httpd") (system? #t) (comment "Apache HTTPD server user") (home-directory "/var/empty") (shell (file-append shadow "/sbin/nologin"))))) (define httpd-shepherd-services (match-lambda (($ <httpd-configuration> package pid-file config) (list (shepherd-service (provision '(httpd)) (documentation "The Apache HTTP Server") (requirement '(networking)) (start #~(make-forkexec-constructor `(#$(file-append package "/bin/httpd") #$@(if config (list "-f" config) '())) #:pid-file #$pid-file)) (stop #~(make-kill-destructor))))))) (define httpd-activation (match-lambda (($ <httpd-configuration> package pid-file config) (match-record config <httpd-config-file> (error-log document-root) #~(begin (use-modules (guix build utils)) (mkdir-p #$(dirname error-log)) (mkdir-p #$document-root)))))) (define (httpd-process-extensions original-config extension-configs) (let ((config (httpd-configuration-config original-config))) (if (httpd-config-file? config) (httpd-configuration (inherit original-config) (config (httpd-config-file (inherit config) (extra-config (append (httpd-config-file-extra-config config) (append-map (match-lambda (($ <httpd-virtualhost> addresses-and-ports contents) `(,(string-append "\n<VirtualHost " addresses-and-ports ">\n") ,@contents "\n</VirtualHost>\n")) ((? string? x) `("\n" ,x "\n")) ((? list? x) `("\n" ,@x "\n"))) extension-configs))))))))) (define httpd-service-type (service-type (name 'httpd) (extensions (list (service-extension shepherd-root-service-type httpd-shepherd-servic