(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) #:use-module (gnu system pam) #: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) #:export (php-fpm-configuration php-fpm-service-type)) (define flatten (@@ (gnu services web) flatten)) (define (@@ (gnu services web) )) (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 . _) (list "env[" variable "] = $" variable "\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 environment-variables) (list (shepherd-service (provision '(php-fpm)) (documentation "Run the php-fpm daemon.") (requirement '(networking)) (start #~(make-forkexec-constructor '(#$(file-append php "/sbin/php-fpm") "--fpm-config" #$(or file (default-php-fpm-config socket user group socket-user socket-group pid-file log-file pm display-errors timezone workers-log-file environment-variables)) #$@(if php-ini-file `("-c" ,php-ini-file) '())) #:environment-variables (cons* #$@(map (match-lambda ((variable . value) #~(string-append #$variable "=" #$value))) environment-variables) (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) (description "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 php-fpm-activation) (service-extension account-service-type php-fpm-accounts))) (default-value (php-fpm-configuration))))