From d364d240ca5a4ce76bf74aee0d4fb71d2338fc20 Mon Sep 17 00:00:00 2001 From: Timo Wilken Date: Sat, 17 Feb 2024 19:09:42 +0100 Subject: Set environment variables in php-fpm configuration ...instead of relying on them to be passed through from the outer environment. PHP-FPM doesn't always do that, including when it's configured as in Guix. --- tw/services/nextcloud.scm | 4 +- tw/services/php-fpm.scm | 175 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 162 insertions(+), 17 deletions(-) (limited to 'tw') diff --git a/tw/services/nextcloud.scm b/tw/services/nextcloud.scm index f8bef474..555ea2d2 100644 --- a/tw/services/nextcloud.scm +++ b/tw/services/nextcloud.scm @@ -276,7 +276,9 @@ opcache.revalidate_freq=120 (body '("return 301 /remote.php$request_uri;")))))))) (service (@ (tw services php-fpm) php-fpm-service-type) - (php-fpm-configuration + ((@ (tw services php-fpm) php-fpm-configuration) + (environment-variables ; Nextcloud News needs this. + `(("SSL_CERT_DIR" . ,(file-append nss-certs "/etc/ssl/certs")))) (php-ini-file %nextcloud-php.ini))) (simple-service 'nextcloud-certificates certbot-service-type diff --git a/tw/services/php-fpm.scm b/tw/services/php-fpm.scm index ff961801..cb351829 100644 --- a/tw/services/php-fpm.scm +++ b/tw/services/php-fpm.scm @@ -1,4 +1,6 @@ (define-module (tw services php-fpm) + #:use-module (gnu packages admin) + #:use-module (gnu packages php) #:use-module (gnu services) #:use-module (gnu services shepherd) #:use-module (gnu services admin) @@ -6,21 +8,131 @@ #:use-module (gnu system shadow) #:use-module (gnu packages certs) #:use-module (guix gexp) + #:use-module (guix records) #:use-module ((guix store) #:select (text-file)) #:use-module ((guix utils) #:select (version-major)) #:use-module ((guix packages) #:select (package-version)) #:use-module (ice-9 match) - #:use-module ((gnu services web) #:select (php-fpm-configuration)) - #:export (php-fpm-service-type)) + #:export (php-fpm-configuration + php-fpm-service-type)) +(define flatten (@@ (gnu services web) flatten)) (define (@@ (gnu services web) )) -(define default-php-fpm-config (@@ (gnu services web) default-php-fpm-config)) +(define + (@@ (gnu services web) )) +(define + (@@ (gnu services web) )) +(define + (@@ (gnu services web) )) + +(define-record-type* php-fpm-configuration + make-php-fpm-configuration + php-fpm-configuration? + (php php-fpm-configuration-php ;file-like + (default php)) + (socket php-fpm-configuration-socket + (default (string-append "/var/run/php" + (version-major (package-version php)) + "-fpm.sock"))) + (user php-fpm-configuration-user + (default "php-fpm")) + (group php-fpm-configuration-group + (default "php-fpm")) + (socket-user php-fpm-configuration-socket-user + (default "php-fpm")) + (socket-group php-fpm-configuration-socket-group + (default "nginx")) + (pid-file php-fpm-configuration-pid-file + (default (string-append "/var/run/php" + (version-major (package-version php)) + "-fpm.pid"))) + (log-file php-fpm-configuration-log-file + (default (string-append "/var/log/php" + (version-major (package-version php)) + "-fpm.log"))) + (process-manager php-fpm-configuration-process-manager + (default ((@ (gnu services web) + php-fpm-dynamic-process-manager-configuration)))) + (display-errors php-fpm-configuration-display-errors + (default #f)) + (timezone php-fpm-configuration-timezone + (default #f)) + (workers-log-file php-fpm-configuration-workers-log-file + (default (string-append "/var/log/php" + (version-major (package-version php)) + "-fpm.www.log"))) + (file php-fpm-configuration-file ;#f | file-like + (default #f)) + (php-ini-file php-fpm-configuration-php-ini-file ;#f | file-like + (default #f)) + (environment-variables php-fpm-configuration-environment-variables ;list of pairs of string + (default '()))) + +(define (default-php-fpm-config socket user group socket-user socket-group + pid-file log-file pm display-errors timezone workers-log-file + environment-variables) + (apply mixed-text-file "php-fpm.conf" + (flatten + "[global]\n" + "pid =" pid-file "\n" + "error_log =" log-file "\n" + "[www]\n" + "user =" user "\n" + "group =" group "\n" + "listen =" socket "\n" + "listen.owner =" socket-user "\n" + "listen.group =" socket-group "\n" + + (if timezone + (string-append "php_admin_value[date.timezone] = \"" timezone "\"\n") + "") + + (match pm + (($ + pm.max-children + pm.start-servers + pm.min-spare-servers + pm.max-spare-servers) + (list + "pm = dynamic\n" + "pm.max_children =" (number->string pm.max-children) "\n" + "pm.start_servers =" (number->string pm.start-servers) "\n" + "pm.min_spare_servers =" (number->string pm.min-spare-servers) "\n" + "pm.max_spare_servers =" (number->string pm.max-spare-servers) "\n")) + + (($ + pm.max-children) + (list + "pm = static\n" + "pm.max_children =" (number->string pm.max-children) "\n")) + + (($ + pm.max-children + pm.process-idle-timeout) + (list + "pm = ondemand\n" + "pm.max_children =" (number->string pm.max-children) "\n" + "pm.process_idle_timeout =" (number->string pm.process-idle-timeout) "s\n"))) + + (map (match-lambda + ((variable . value) + (list "env[" variable "] =" value "\n"))) + environment-variables) + + "php_flag[display_errors] = " (if display-errors "on" "off") "\n" + + (if workers-log-file + (list "catch_workers_output = yes\n" + "php_admin_value[error_log] =" workers-log-file "\n" + "php_admin_flag[log_errors] = on\n") + (list "catch_workers_output = no\n"))))) (define php-fpm-shepherd-service (match-lambda (($ php socket user group socket-user socket-group pid-file log-file pm display-errors - timezone workers-log-file file php-ini-file) + timezone workers-log-file file php-ini-file + environment-variables) (list (shepherd-service (provision '(php-fpm)) (documentation "Run the php-fpm daemon.") @@ -31,18 +143,52 @@ #$(or file (default-php-fpm-config socket user group socket-user socket-group pid-file log-file - pm display-errors timezone workers-log-file)) + pm display-errors timezone workers-log-file + environment-variables)) #$@(if php-ini-file `("-c" ,php-ini-file) '())) - ;; XXX: this stanza added, for Nextcloud News - #:environment-variables - (cons* - (string-append "SSL_CERT_DIR=" #$nss-certs "/etc/ssl/certs") - (default-environment-variables)) #:pid-file #$pid-file)) (stop #~(make-kill-destructor))))))) +;; Same as upstream, but we have to copy it to make it match our overridden configuration. +(define php-fpm-accounts + (match-lambda + (($ php socket user group socket-user socket-group) + `(,@(if (equal? group "php-fpm") + '() + (list (user-group (name "php-fpm") (system? #t)))) + ,(user-group + (name group) + (system? #t)) + ,(user-account + (name user) + (group group) + (supplementary-groups '("php-fpm")) + (system? #t) + (comment "php-fpm daemon user") + (home-directory "/var/empty") + (shell (file-append shadow "/sbin/nologin"))))))) + +;; Same as upstream, but we have to copy it to make it match our overridden configuration. +(define (php-fpm-activation config) + #~(begin + (use-modules (guix build utils)) + (let* ((user (getpwnam #$(php-fpm-configuration-user config))) + (touch (lambda (file-name) + (call-with-output-file file-name (const #t)))) + (workers-log-file + #$(php-fpm-configuration-workers-log-file config)) + (init-log-file + (lambda (file-name) + (when workers-log-file + (when (not (file-exists? file-name)) + (touch file-name)) + (chown file-name (passwd:uid user) (passwd:gid user)) + (chmod file-name #o660))))) + (init-log-file #$(php-fpm-configuration-log-file config)) + (init-log-file workers-log-file)))) + (define php-fpm-service-type (service-type (name 'php-fpm) @@ -50,10 +196,7 @@ "Run @command{php-fpm} to provide a fastcgi socket for calling php through a webserver.") (extensions - (list (service-extension shepherd-root-service-type - php-fpm-shepherd-service) - (service-extension activation-service-type - (@@ (gnu services web) php-fpm-activation)) - (service-extension account-service-type - (@@ (gnu services web) php-fpm-accounts)))) + (list (service-extension shepherd-root-service-type php-fpm-shepherd-service) + (service-extension activation-service-type php-fpm-activation) + (service-extension account-service-type php-fpm-accounts))) (default-value (php-fpm-configuration)))) -- cgit v1.2.3