From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42851) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e1g0w-0000N8-Fw for guix-patches@gnu.org; Mon, 09 Oct 2017 17:55:12 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e1g0t-0007gk-3g for guix-patches@gnu.org; Mon, 09 Oct 2017 17:55:06 -0400 Received: from debbugs.gnu.org ([208.118.235.43]:50111) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1e1g0s-0007gd-Uc for guix-patches@gnu.org; Mon, 09 Oct 2017 17:55:03 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1e1g0s-0003eH-Mf for guix-patches@gnu.org; Mon, 09 Oct 2017 17:55:02 -0400 Subject: [bug#28769] [PATCH] gnu: services: Add php-fpm. Resent-Message-ID: Received: from eggs.gnu.org ([2001:4830:134:3::10]:42744) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e1g0P-0000LW-N8 for guix-patches@gnu.org; Mon, 09 Oct 2017 17:54:35 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e1g0M-0007PU-Bn for guix-patches@gnu.org; Mon, 09 Oct 2017 17:54:33 -0400 Received: from cock.li ([185.100.85.212]:55458) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e1g0L-0007Oc-PG for guix-patches@gnu.org; Mon, 09 Oct 2017 17:54:30 -0400 From: nee Message-ID: <9fe1701f-d78f-ba3a-37eb-64417337a55b@cock.li> Date: Mon, 9 Oct 2017 23:54:24 +0200 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------24EA37E412088F5A88ABFFD3" Content-Language: en-GB List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+kyle=kyleam.com@gnu.org Sender: "Guix-patches" To: 28769@debbugs.gnu.org This is a multi-part message in MIME format. --------------24EA37E412088F5A88ABFFD3 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hello, this adds a php-fpm service. php-fpm is an alternative fcgi implementation that is already build with the php package. About the accounts: Nginx needs write access to the unix socket of php-fpm. I didn't want to set nginx as default user for php-fpm in case we add other webservers, so I added the nginx to the newly created www-data group. Thank you for reading. I'm looking forward to the revisions, and happy Hacking! --------------24EA37E412088F5A88ABFFD3 Content-Type: text/x-patch; name="0001-guix-utils-add-version-major.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0001-guix-utils-add-version-major.patch" =46rom c31e09144c4cb8cd02d6fdb716760d385eee10d4 Mon Sep 17 00:00:00 2001 From: nee Date: Mon, 9 Oct 2017 23:02:05 +0200 Subject: [PATCH 1/2] guix: utils: add version-major. * guix/utils.scm (version-major): New function. --- guix/utils.scm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/guix/utils.scm b/guix/utils.scm index de4aa6531..cec209a8f 100644 --- a/guix/utils.scm +++ b/guix/utils.scm @@ -72,6 +72,7 @@ version>=3D? version-prefix version-major+minor + version-major guile-version>? string-replace-substring arguments-from-environment-variable @@ -488,6 +489,10 @@ For example, (version-prefix \"2.1.47.4.23\" 3) retu= rns \"2.1.47\"" minor version numbers from version-string." (version-prefix version-string 2)) =20 +(define (version-major version-string) + "Return the major version number as string from the version-string." + (version-prefix version-string 1)) + (define (version>? a b) "Return #t when A denotes a version strictly newer than B." (eq? '> (version-compare a b))) --=20 2.14.1 --------------24EA37E412088F5A88ABFFD3 Content-Type: text/x-patch; name="0002-gnu-services-Add-php-fpm.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0002-gnu-services-Add-php-fpm.patch" =46rom d78ba26e322b4f12a20a94f5334d23ba2ea6d4d5 Mon Sep 17 00:00:00 2001 From: nee Date: Mon, 9 Oct 2017 23:06:05 +0200 Subject: [PATCH 2/2] gnu: services: Add php-fpm. * gnu/services/web.scm (, ): New record types. (php-fpm-configuration?, php-fpm-process-manager-configuration?, php-fpm-service-type, nginx-php-location): New procedures. * doc/guix.texi (Web-Services): document php-fpm service. --- doc/guix.texi | 93 +++++++++++++++++++++++++++ gnu/services/web.scm | 173 +++++++++++++++++++++++++++++++++++++++++++++= +++++- 2 files changed, 264 insertions(+), 2 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index f0a59a6b4..ed4336f64 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -14529,6 +14529,99 @@ capability also has to be configured on the fron= t-end as well. @end deftp =20 =20 +@cindex php-fpm +PHP-FPM (FastCGI Process Manager) is an alternative PHP FastCGI implemen= tation +with some additional features useful for sites of any size. + +@defvr {Scheme Variable} php-fpm-service-type +A Service type for @code{php-fpm}. +@end defvr + +@deftp {Data Type} php-fpm-configuration +Data Type for php-fpm service configuration. +@table @asis +@item @code {socket} (default: @code{(string-append "/var/run/php" (vers= ion-major (package-version php)) "-fpm.sock")}) +The address on which to accept FastCGI requests. Valid syntaxes are: +@table @asis +@item @code{"ip.add.re.ss:port"} +Listen on a TCP socket to a specific address on a specific port. +@item @code{"port"} +Listen on a TCP socket to all addresses on a specific port. +@item @code{"/path/to/unix/socket"} +Listen on a unix socket. +@end table + +@item @code {user} (default: @code{php-fpm}) +User who will own the php worker processes. +@item @code {group} (default: @code{php-fpm}) +Group of the worker processes. +@item @code {socket-user} (default: @code{nginx}) +User who can speak to the php-fpm socket. +@item @code {socket-group} (default: @code{nginx}) +Group that can speak to the php-fpm socket. +@item @code {process-manager} (default: @code{(php-fpm-process-manager-c= onfiguration)}) +Detailed settings for the php-fpm process manager. +@item @code {display-errors} (default @code{#f}) +Determines wether php errors and warning should be sent to clients +and displayed in their browsers. +This is useful for local php development, but a security risk for public= sites, +as error messages can reveal passwords and personal data. +@item @code {workers-logfile} (default @code{(string-append "/var/log/ph= p" (version-major (package-version php)) "-fpm.log")}) +This file will log the @code{stderr} outputs of php worker processes. +Can be set to @code{#f} to disable logging. +@item @code {file} (default @code{#f}) +An optional override of the whole configuration. +You can use the @code{mixed-text-file} function or an absolute filepath = for it. +@end table +@end deftp + +@deftp {Data type} php-fpm-process-manager-configuration +Data Type for php-fpm worker process limits. +@table @asis +@item @code {type} (default: @code{"dynamic"}) +@table @asis +@item @code{"dynamic"} +Spare worker processes are kept around based on the set @code{php-fpm-pr= ocess-manager-configuration} limits. +@item @code{"static"} +A static number of worker processes is created. +@item @code{"ondemand"} +Worker processes are only created on demand. +@end table +@item @code {max-children} (default: @code{5}) +Maximum of worker processes. Applies when the type is @code{"static"}, @= code{"dynamic"}, or @code{"ondemand"}. +@item @code {start-servers} (default: @code{2}) +How many worker processes should be started on start-up. Only applies wh= en type is @code{"dynamic"}. +@item @code {min-spare-servers} (default: @code{1}) +How many spare worker processes should be kept around at minimum. Only a= pplies when type is @code{"dynamic"}. +@item @code {max-spare-servers} (default: @code{3}) +How many spare worker processes should be kept around at maximum. Only a= pplies when type is @code{"dynamic"}. +@item @code {process-idle-timeout} (default: @code{10}) +The time in seconds after which a process with no requests is killed. On= ly applies when type is @code{"ondemand"}. +@end table +@end deftp + +@defvr {Scheme Variable} nginx-php-fpm-location +A helper function to quickly add php to an @code{nginx-server-configurat= ion}. +@end defvr + +A simple services setup for nginx with php can look like this: +@example +(services (cons* (dhcp-client-service) + (service php-fpm-service-type + (php-fpm-configuration)) + (service nginx-service-type + (nginx-server-configuration + (server-name '("example.com")) + (root "/srv/http/") + (locations + (list (nginx-php-location))) + (https-port #f) + (ssl-certificate #f) + (ssl-certificate-key #f))) + %base-services)) +@end example + + @node DNS Services @subsubsection DNS Services @cindex DNS (domain name system) diff --git a/gnu/services/web.scm b/gnu/services/web.scm index 9d713003c..fd63b15bb 100644 --- a/gnu/services/web.scm +++ b/gnu/services/web.scm @@ -26,8 +26,11 @@ #:use-module (gnu system shadow) #:use-module (gnu packages admin) #:use-module (gnu packages web) + #:use-module (gnu packages php) #:use-module (guix records) #:use-module (guix gexp) + #:use-module ((guix utils) #:select (version-major)) + #:use-module ((guix packages) #:select (package-version)) #:use-module (srfi srfi-1) #:use-module (ice-9 match) #:export ( @@ -76,7 +79,14 @@ =20 fcgiwrap-configuration fcgiwrap-configuration? - fcgiwrap-service-type)) + fcgiwrap-service-type + + php-fpm-configuration + php-fpm-configuration? + php-fpm-process-manager-configuration + php-fpm-process-manager-configuration? + php-fpm-service-type + nginx-php-location)) =20 ;;; Commentary: ;;; @@ -256,10 +266,12 @@ of index files." "events {}\n"))) =20 (define %nginx-accounts - (list (user-group (name "nginx") (system? #t)) + (list (user-group (name "www-data") (system? #t)) + (user-group (name "nginx") (system? #t)) (user-account (name "nginx") (group "nginx") + (supplementary-groups '("www-data")) (system? #t) (comment "nginx server user") (home-directory "/var/empty") @@ -385,3 +397,160 @@ of index files." (service-extension account-service-type fcgiwrap-accounts))) (default-value (fcgiwrap-configuration)))) + +(define-record-type* php-fpm-configuration + make-php-fpm-configuration + php-fpm-configuration? + (php php-fpm-configuration-php ; + (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 "nginx")) + (socket-group php-fpm-configuration-socket-group + (default "nginx")) + (process-manager php-fpm-configuration-process-manager + (default (php-fpm-process-manager-configuration))) + (display-errors php-fpm-configuration-display-errors + (default #f)) + (workers-logfile php-fpm-configuration-workers-logfile + (default (string-append "/var/log/php" + (version-major (package-version= php)) + "-fpm.log"))) + (file php-fpm-configuration-file ;#f | file-like + (default #f))) + +(define-record-type* php-fpm-pro= cess-manager-configuration + make-php-fpm-process-manager-configuration + php-fpm-process-manager-configuration? + (type php-fpm-process-manager-configuration-type + (default "dynamic")) + (max-children php-fpm-process-manager-configuration-max-childr= en + (default 5)) + (start-servers php-fpm-process-manager-configuration-start-serv= ers + (default 2)) + (min-spare-servers php-fpm-process-manager-configuration-min-spare-= servers + (default 1)) + (max-spare-servers php-fpm-process-manager-configuration-max-spare-= servers + (default 3)) + (process-idle-timeout php-fpm-process-manager-configuration-process-id= le-timeout + (default 10))) + +(define php-fpm-accounts + (match-lambda + (($ php socket user group socket-user socket= -group _ _ _ _) + (filter identity + (list + (user-group (name "www-data") (system? #t)) + (and (equal? group "php-fpm") + (user-group + (name "php-fpm") + (system? #t))) + (and (equal? user "php-fpm") + (user-account + (name "php-fpm") + (group group) + (supplementary-groups '("www-data")) + (system? #t) + (comment "web services group") + (home-directory "/var/empty") + (shell (file-append shadow "/sbin/nologin"))))))))) + +(define (default-php-fpm-config socket user group socket-user socket-gro= up + pm display-errors workers-logfile) + (match + pm + (($ pm.type + pm.max-children + pm.start-servers + pm.min-spare-servers + pm.max-spare-servers + pm.process-idle-timeout)= + (apply mixed-text-file "php-fpm.conf" + "[global]\n" + "[www]\n" + "user =3D" user "\n" + "group =3D" group "\n" + "listen =3D" socket "\n" + "listen.owner =3D" socket-user "\n" + "listen.group =3D" socket-group "\n" + + "pm =3D" pm.type "\n" + "pm.max_children =3D" (number->string pm.max-children) "\n" + "pm.start_servers =3D" (number->string pm.start-servers) "\n= " + "pm.min_spare_servers =3D" (number->string pm.min-spare-serv= ers) "\n" + "pm.max_spare_servers =3D" (number->string pm.max-spare-serv= ers) "\n" + "pm.process_idle_timeout =3D" (number->string pm.process-idl= e-timeout) "s\n" + + "php_flag[display_errors] =3D " (if display-errors "on" "off= ") "\n" + + (if workers-logfile + (list "catch_workers_output =3D yes\n" + "php_admin_value[error_log] =3D" workers-logfile "= \n" + "php_admin_flag[log_errors] =3D on\n") + (list "catch_workers_output =3D no\n")))))) + +(define php-fpm-shepherd-service + (match-lambda + (($ php socket user group socket-user socket= -group + pm display-errors workers-logfile file) + (list (shepherd-service + (provision '(php-fpm)) + (documentation "Run the php-fpm daemon.") + (requirement '(networking)) + (start #~(make-forkexec-constructor + '(#$(file-append php "/sbin/php-fpm") + "--nodaemonize" "-p" "/var" "--fpm-config" + #$(or file + (default-php-fpm-config socket user group + socket-user socket-group pm display-erro= rs + workers-logfile))))) + (stop #~(make-kill-destructor))))))) + +(define php-fpm-activation + (match-lambda + (($ _ _ user _ _ _ _ _ workers-logfile _) + #~(begin + (use-modules (guix build utils)) + (let ((user (getpwnam #$user)) + (touch (lambda (file-name) + (call-with-output-file file-name (const #t))))) + ;; prepare writable logfile + (when #$workers-logfile + (when (not (file-exists? #$workers-logfile)) + (touch #$workers-logfile)) + (chown #$workers-logfile (passwd:uid user) (passwd:gid user= )) + (chmod #$workers-logfile #o660))))))) + + +(define php-fpm-service-type + (service-type (name 'php-fpm) + (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)))) + +(define* (nginx-php-location + #:key + (nginx-package nginx) + (socket (string-append "/var/run/php" + (version-major (package-version php)) + "-fpm.sock"))) + "Return a nginx-location-configuration that makes nginx run .php files= =2E" + (nginx-location-configuration + (uri "~ \\.php$") + (body (list + "fastcgi_split_path_info ^(.+\\.php)(/.+)$;" + (string-append "fastcgi_pass unix:" socket ";") + "fastcgi_index index.php;" + (list "include " nginx-package "/share/nginx/conf/fastcgi.conf= ;"))))) --=20 2.14.1 --------------24EA37E412088F5A88ABFFD3--