From unknown Sat Jun 21 10:46:48 2025 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Mailer: MIME-tools 5.509 (Entity 5.509) Content-Type: text/plain; charset=utf-8 From: bug#28769 <28769@debbugs.gnu.org> To: bug#28769 <28769@debbugs.gnu.org> Subject: Status: [PATCH] gnu: services: Add php-fpm. Reply-To: bug#28769 <28769@debbugs.gnu.org> Date: Sat, 21 Jun 2025 17:46:48 +0000 retitle 28769 [PATCH] gnu: services: Add php-fpm. reassign 28769 guix-patches submitter 28769 nee severity 28769 normal tag 28769 patch thanks From debbugs-submit-bounces@debbugs.gnu.org Mon Oct 09 17:54:46 2017 Received: (at submit) by debbugs.gnu.org; 9 Oct 2017 21:54:46 +0000 Received: from localhost ([127.0.0.1]:58792 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e1g0b-0003dc-HF for submit@debbugs.gnu.org; Mon, 09 Oct 2017 17:54:46 -0400 Received: from eggs.gnu.org ([208.118.235.92]:51776) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e1g0Z-0003dN-Hw for submit@debbugs.gnu.org; Mon, 09 Oct 2017 17:54:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e1g0S-0007Qa-5m for submit@debbugs.gnu.org; Mon, 09 Oct 2017 17:54:38 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=0.8 required=5.0 tests=BAYES_50,T_DKIM_INVALID autolearn=disabled version=3.3.2 Received: from lists.gnu.org ([2001:4830:134:3::11]:53855) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e1g0R-0007QW-Uj for submit@debbugs.gnu.org; Mon, 09 Oct 2017 17:54:36 -0400 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 To: guix-patches@gnu.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cock.li; s=mail; t=1507586065; bh=2kvkBL5bi5oCfiPKx4azDuC09cBBiw6MXcZ5NMjjJDI=; h=To:From:Subject:Date:From; b=X+6hf3TaqqOPI5ogYTy4k3z1sTipg9J0taQurm0lz4rlzrmaWsp77oaEumFkQceX3 jsiJROkskRa5vnppoWzjhoPXBd6sNVPKMm4S3i7CQHLbiGeYmYnZbidefBg+Mc/PAm ZL+DnwW2fb1Ewcq/ObhyNAJM9pviwFj17+ioLnwsErz/A4/p0WqQE1uvWpjQuINIWh g64U2WNFVeO2VAx24s+6WNDWPjGVY2NRgWA42ZzcH+uq2pP2+aZXY06K8QyVCYKZzw YjAs4b8Pr2SYEZ6aoy8S5M1wieYd9cPFK3DOTP1uoy9wIQ5G7lNc9vZElKfAJgLRzy kOgBDI4ScAZCg== From: nee Subject: [PATCH] gnu: services: Add php-fpm. Message-ID: <9fe1701f-d78f-ba3a-37eb-64417337a55b@cock.li> Date: Mon, 9 Oct 2017 23:54:24 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.3.0 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------24EA37E412088F5A88ABFFD3" Content-Language: en-GB X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Received-From: 2001:4830:134:3::11 X-Spam-Score: -4.1 (----) X-Debbugs-Envelope-To: submit X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -4.1 (----) 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-- From debbugs-submit-bounces@debbugs.gnu.org Fri Oct 13 16:06:18 2017 Received: (at 28769) by debbugs.gnu.org; 13 Oct 2017 20:06:18 +0000 Received: from localhost ([127.0.0.1]:38447 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e36Dq-0003JK-FB for submit@debbugs.gnu.org; Fri, 13 Oct 2017 16:06:18 -0400 Received: from li622-129.members.linode.com ([212.71.249.129]:55126 helo=mira.cbaines.net) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e36Dn-0003JA-Rq for 28769@debbugs.gnu.org; Fri, 13 Oct 2017 16:06:16 -0400 Received: by mira.cbaines.net (Postfix, from userid 113) id CE4AF147650; Fri, 13 Oct 2017 21:06:13 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00, T_FRT_COCK,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from localhost (cpc102582-walt20-2-0-cust14.13-2.cable.virginm.net [86.27.34.15]) by mira.cbaines.net (Postfix) with ESMTPSA id C302614764E; Fri, 13 Oct 2017 21:06:12 +0100 (BST) Date: Fri, 13 Oct 2017 21:06:08 +0100 From: Christopher Baines To: nee Subject: Re: [bug#28769] [PATCH] gnu: services: Add php-fpm. Message-ID: <20171013210608.69664320@cbaines.net> In-Reply-To: <9fe1701f-d78f-ba3a-37eb-64417337a55b@cock.li> References: <9fe1701f-d78f-ba3a-37eb-64417337a55b@cock.li> X-Mailer: Claws Mail 3.15.1-dirty (GTK+ 2.24.31; x86_64-unknown-linux-gnu) MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; boundary="Sig_/O+fRgFTDr6o3OgWnbmgL/pC"; protocol="application/pgp-signature" X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 28769 Cc: 28769@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) --Sig_/O+fRgFTDr6o3OgWnbmgL/pC Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable On Mon, 9 Oct 2017 23:54:24 +0200 nee wrote: > Subject: [PATCH 1/2] guix: utils: add version-major. >=20 > * guix/utils.scm (version-major): New function. I think procedure, rather than function is the usual, at least within the context of commit messages in the guix repository. > --- > guix/utils.scm | 5 +++++ > 1 file changed, 5 insertions(+) >=20 > 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? =20 > 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) > returns \"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)) > + Seems fine to me. I'm guessing that you added this because it was convenient, but I can't see it being used in the next patch, have I missed it? --Sig_/O+fRgFTDr6o3OgWnbmgL/pC Content-Type: application/pgp-signature Content-Description: OpenPGP digital signature -----BEGIN PGP SIGNATURE----- iQKTBAEBCgB9FiEEPonu50WOcg2XVOCyXiijOwuE9XcFAlnhHLBfFIAAAAAALgAo aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldDNF ODlFRUU3NDU4RTcyMEQ5NzU0RTBCMjVFMjhBMzNCMEI4NEY1NzcACgkQXiijOwuE 9XfqAA//dXi/rbR2zWFZy2Bq0WnOx9zV7mj5kw+oNKd3VK+8nQ3V4SgvpD/5eM8J vf6exWiZuo1w7ZjNjSVdgEm/+zz9ZrwsdaYfDdOqPa23i3t3VYUp9AJIyhILVNwt 65UtzQwpwB0HOEDpqbq60k+GkpPJEeBMkSgpNwZEcR8cWBNHrvzIlTSq6/98R02N sK4IjPbrbHs3EX2/eSVn71DiNPB2b9EQT4eSbY2mxMa1dwiMfigfa5ashlUYg7V0 Iq5iXhKGa/Ily/x1pYyUcZMDuxivV/C488uWkBc98Kn1psjselIjTJ5rTeXSjSAU AzXFhxQFiJ2LOzPySoH0zi8y+gaKnsVVY2H7rbCfVtQ0CP8OBzSXDg6DieKU4Zwo kIDm74flNy0VYlXh8ogrrl6j7HmYdbRYZgw+QQijp2YZtJh4eG2Dv6XvVN7F6yHP 63LyEU7gy4yuXj6AI6hovkZwdKWuM0b1/kGHGo5xKFavPFj94bWKbbDuplyWvp1+ NvitNq/xD92sUvDPUt9TzdA+ZUlV2EW1POiZmt1IaCma55sm5IhZ6EfCl31H3qSd 4VZkWsC9xmAiYvSPbl6R4ci6pcxTsxe5MpMeNz8FC/JLOPJwDlOUwA1V0ITkylL0 MHuPZ3wdCaHmsvr5iaEc/aGb+v3JOLkz5leFMH5hSfldtxxHhz8= =FK1Z -----END PGP SIGNATURE----- --Sig_/O+fRgFTDr6o3OgWnbmgL/pC-- From debbugs-submit-bounces@debbugs.gnu.org Fri Oct 13 16:09:04 2017 Received: (at 28769) by debbugs.gnu.org; 13 Oct 2017 20:09:04 +0000 Received: from localhost ([127.0.0.1]:38451 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e36GV-0003Nc-TA for submit@debbugs.gnu.org; Fri, 13 Oct 2017 16:09:04 -0400 Received: from li622-129.members.linode.com ([212.71.249.129]:55131 helo=mira.cbaines.net) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e36GT-0003NC-NX for 28769@debbugs.gnu.org; Fri, 13 Oct 2017 16:09:02 -0400 Received: by mira.cbaines.net (Postfix, from userid 113) id 1B58214764F; Fri, 13 Oct 2017 21:09:01 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00, T_FRT_COCK,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from localhost (cpc102582-walt20-2-0-cust14.13-2.cable.virginm.net [86.27.34.15]) by mira.cbaines.net (Postfix) with ESMTPSA id CEAE214764E; Fri, 13 Oct 2017 21:09:00 +0100 (BST) Date: Fri, 13 Oct 2017 21:09:00 +0100 From: Christopher Baines To: nee Subject: Re: [bug#28769] [PATCH] gnu: services: Add php-fpm. Message-ID: <20171013210900.6a709a78@cbaines.net> In-Reply-To: <20171013210608.69664320@cbaines.net> References: <9fe1701f-d78f-ba3a-37eb-64417337a55b@cock.li> <20171013210608.69664320@cbaines.net> X-Mailer: Claws Mail 3.15.1-dirty (GTK+ 2.24.31; x86_64-unknown-linux-gnu) MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; boundary="Sig_/8NQ0QztdUnd5qSkz.qCkPEc"; protocol="application/pgp-signature" X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 28769 Cc: 28769@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) --Sig_/8NQ0QztdUnd5qSkz.qCkPEc Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable On Fri, 13 Oct 2017 21:06:08 +0100 Christopher Baines wrote: > On Mon, 9 Oct 2017 23:54:24 +0200 > nee wrote: ... > > +(define (version-major version-string) > > + "Return the major version number as string from the > > version-string." > > + (version-prefix version-string 1)) > > + =20 >=20 > Seems fine to me. I'm guessing that you added this because it was > convenient, but I can't see it being used in the next patch, have I > missed it? Yep, I missed it, but I see it now, problem solved :) --Sig_/8NQ0QztdUnd5qSkz.qCkPEc Content-Type: application/pgp-signature Content-Description: OpenPGP digital signature -----BEGIN PGP SIGNATURE----- iQKTBAEBCgB9FiEEPonu50WOcg2XVOCyXiijOwuE9XcFAlnhHVxfFIAAAAAALgAo aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldDNF ODlFRUU3NDU4RTcyMEQ5NzU0RTBCMjVFMjhBMzNCMEI4NEY1NzcACgkQXiijOwuE 9XfTAQ/9HzX47E7FNlwzHze6X28d0bZ3RSB5suqpmZlqXzz9G591VPMaJdQJTx/J xK73hHS00wXCrrAHXn8DXmr7Sls5bPcPW8G4mdO+gxLTj5GUHD5DhOJhXikwnI1l a9wyu0b3iJQ84UyWTW9DvXWyx9S+cez3LQkez3f6JiMHi3/+1288ea9/lYaEZToG Uq/KgEBc1flmx3IW4YVG7dw2RUV8AmE0JMMsHVy8OJ7D6d9/c6uk7wLa1zZI61J0 oSMdNJpZAFNC4o62zEFXO10tNtkYJE+Ne7wqYtJd4zbDuLoNF+OuR/t2rhYhziOO wf7KPA96tCsuKAE7qKvK1Gj5KXR3Ch/NNAnQtQVED/wKu38TYB3RSEe9XHzxDSlG ga3wlJul6HhpiOZe62nDaPZXvTfR/tQnYT+M7zGvSivVZZ4TsWTmNgqf3aRxtJDa 06SgDhYbvlDWWiOOM0gtHVIsp7epuT0VgqPwHNCRSoVBpzZ0NaWXOLy1H9ZcySfi G8eyGIHJfpLtUlPb+yjZBFa+NQS0R0/0tlOzqvPQxNPyB41zpmNeN09XZyFBuG7i kBenB6P5zJbTyvO6Ygr9khu/kDYrs4wkANrRKOtS414W/7/RGz8kqKYdTgo3DijQ SbgQDEUGTwaH5jeyTiSDn9ZjAirP2M3nhgOqXMgDBtwLnj2xU5U= =LsqT -----END PGP SIGNATURE----- --Sig_/8NQ0QztdUnd5qSkz.qCkPEc-- From debbugs-submit-bounces@debbugs.gnu.org Fri Oct 13 17:37:43 2017 Received: (at 28769) by debbugs.gnu.org; 13 Oct 2017 21:37:43 +0000 Received: from localhost ([127.0.0.1]:38530 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e37eJ-0007Xl-6w for submit@debbugs.gnu.org; Fri, 13 Oct 2017 17:37:43 -0400 Received: from li622-129.members.linode.com ([212.71.249.129]:55188 helo=mira.cbaines.net) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e37eG-0007Xa-FE for 28769@debbugs.gnu.org; Fri, 13 Oct 2017 17:37:41 -0400 Received: by mira.cbaines.net (Postfix, from userid 113) id 905C914764F; Fri, 13 Oct 2017 22:37:38 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00, T_FRT_COCK,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from localhost (cpc102582-walt20-2-0-cust14.13-2.cable.virginm.net [86.27.34.15]) by mira.cbaines.net (Postfix) with ESMTPSA id 6064214764E; Fri, 13 Oct 2017 22:37:36 +0100 (BST) Date: Fri, 13 Oct 2017 22:37:29 +0100 From: Christopher Baines To: nee Subject: Re: [bug#28769] [PATCH] gnu: services: Add php-fpm. Message-ID: <20171013223729.2605f33c@cbaines.net> In-Reply-To: <9fe1701f-d78f-ba3a-37eb-64417337a55b@cock.li> References: <9fe1701f-d78f-ba3a-37eb-64417337a55b@cock.li> X-Mailer: Claws Mail 3.15.1-dirty (GTK+ 2.24.31; x86_64-unknown-linux-gnu) MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; boundary="Sig_/Qc8BM_/nhJCc9gM/Eo9Ab.L"; protocol="application/pgp-signature" X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 28769 Cc: 28769@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) --Sig_/Qc8BM_/nhJCc9gM/Eo9Ab.L Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable On Mon, 9 Oct 2017 23:54:24 +0200 nee wrote: > Subject: [PATCH 2/2] gnu: services: Add php-fpm. Hey, I've never used php-fpm, but I'll have a go at reviewing this :) > * 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. Very minor, but I'd suggest "(Web Services): Document the php-fpm service." here. > --- > doc/guix.texi | 93 +++++++++++++++++++++++++++ > gnu/services/web.scm | 173 > ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, > 264 insertions(+), 2 deletions(-) >=20 > 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 > front-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. If these additional features are worth mentioning, it would be best to be specific as to what they are, and what benefit they provide. > +@defvr {Scheme Variable} php-fpm-service-type > +A Service type for @code{php-fpm}. > +@end defvr > + ... > +@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 Reading this makes me think that maybe having record types per process manager types might be useful, e.g. > +@defvr {Scheme Variable} nginx-php-fpm-location > +A helper function to quickly add php to an > @code{nginx-server-configuration}. +@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)) The default-value for the service type means that you can omit the (php-fpm-configuration) here, as (service php-fpm-service-type) should work. > + (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)) When using other Guix services, I've run in to problems when field accessors and record types were not exported. The biggest cost I can think of is the lines of code, but I'd still suggest to export everything by default here. > ;;; 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") Pulling in your comment about the accounts... > 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. This sounds like it would work, however, the defaults for the socket-user and socket-group of the php-fpm-configuration are currently "nginx", which seems to disagree with what you say above? Also, the idea that came to my mind for this is to add php-fpm as a supplementary group for the nginx user. In my mind, this seems the neatest way of giving nginx access to the socket. What do you think? I suggest this, as I'm not sure the name of the www-data group does a good job of describing that it's controlling access to a socket. Also, giving nginx explicit access to things owned by the php-fpm group could be more secure than using a more generic group, especially as other services that might need access to the socket, could end up getting it because they need access to other things using the www-data group. If the above sounds like a good idea, I think it could be implemented by adding a configurable list of supplementary groups to the nginx-service-type. Then maybe even adding support for configuring this via the service extensions mechanism, then having the php-fpm-service-type extending the nginx-service-type... The above is definitely to complicated to do all in one go, especially since the nginx-service-type doesn't support anything more complicated than adding server blocks through extension at the moment. > @@ -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")) As above, I'm not sure the use of nginx here matches the description you gave...? > + (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"))) I'm not sure the php is adding much to the log file name, but then again I've never used php... what do you think? > + (file php-fpm-configuration-file ;#f | file-like > + (default #f))) > + > +(define-record-type* > php-fpm-process-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-children > + (default 5)) > + (start-servers > php-fpm-process-manager-configuration-start-servers > + (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-idle-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"))))))))) + As you can specify the user and group in the , I think it might be better to just use the user and group names from there, and always setup a user and group with those names, I'm guessing that this will be what the average user would expect to happen. > +(define (default-php-fpm-config socket user group socket-user > socket-group > + 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-servers) "\n" > + "pm.max_spare_servers =3D" (number->string > pm.max-spare-servers) "\n" > + "pm.process_idle_timeout =3D" (number->string > pm.process-idle-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-errors > + workers-logfile))))) > + (stop #~(make-kill-destructor))))))) As php-fpm supports using a pid file, I'd recommend configuring both php-fpm and shepherd to use this by default. It means that the shepherd service will wait until php-fpm creates the PID file before starting services that say they require it, which can prevent some issues. > +(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)))) Filling in the description (a relatively new field on the service type) would be a great addition here. > +(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." > + (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;"))))) This helper seems good, although I think putting the "include" elsewhere would be better, and I recognise that this isn't possible with the nginx service yet. Overall, I think this is great. Excellent use of record types, gexps and match expressions. I think it would be good to think more on the accounts issue before merging, but that is all that comes to mind currently. Also, if you feel like it, as service test would be a great addition to this patch. There is a test for nginx already in gnu/tests/web.scm, and I think you could get most of the benefit by having a test for nginx with php-fpm, as that would give you some coverage over the php-fpm service, as well as the nginx configuration. --Sig_/Qc8BM_/nhJCc9gM/Eo9Ab.L Content-Type: application/pgp-signature Content-Description: OpenPGP digital signature -----BEGIN PGP SIGNATURE----- iQKTBAEBCgB9FiEEPonu50WOcg2XVOCyXiijOwuE9XcFAlnhMhlfFIAAAAAALgAo aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldDNF ODlFRUU3NDU4RTcyMEQ5NzU0RTBCMjVFMjhBMzNCMEI4NEY1NzcACgkQXiijOwuE 9XcSYg/+NNhbP1jgyrloI41SIMbKWNozRSwcCLIpziGsir8r79x6MYgLnS6Ou9kP ci5GMjEcCwbne6JgbfcDghfvZ244WkuhK8gGtNuRE/80+7xdFM1PtJJNTWlyROfi PVsiOjo3BEi18OBr0on/811rRHeac1Kzc71JfH9mlA4W0xA1bQFs2p33ModPA1RG uKc5eJE4ieeH24C8sxxJz68JOaN4NA9mKx99+b9MMwUR0b7sn9o2DhHizXj5CYcd 8ho++VyZ45AMJlU4BEucW2G5g0gWYC5DeYsyyP8nr+H7l8WZiAVa/J2L/ZcAoh/U +NEPw6+5OiYd67ttFMolcRgLiwaMytklcoHp9B2iHvgXnGWAN5ALCwXkLEs15zRL Io6YnLHsVDf9ELjMXTwquBRV4AjCq/rwPRqqZEez50Nxl+xc48QLo/ElglEgseA0 5Cln6ymzZE2eK0yt7RJr3uMyMYL6d8rgwXEE2VNML4MxfxjFiTAX8OCkBBufx2+b WFpDd9khaYFN3TgKYiaq1od4/J03tgZI9AS7HmJ8fWeKFFkWB556E9es9MNdoJW2 n93Su4KSgI2szHdvaBbOZ7+ET567qQ7x6eCsL6hi9YmbI0UgjHeQu3evOouws9oS MGHzKMbe1potlmfFqs5KDJVVbM/n8zwU/oxxndhMaQmZkBEuhtc= =NPA9 -----END PGP SIGNATURE----- --Sig_/Qc8BM_/nhJCc9gM/Eo9Ab.L-- From debbugs-submit-bounces@debbugs.gnu.org Mon Oct 16 17:39:04 2017 Received: (at 28769) by debbugs.gnu.org; 16 Oct 2017 21:39:04 +0000 Received: from localhost ([127.0.0.1]:44353 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e4D6F-0006jc-Gb for submit@debbugs.gnu.org; Mon, 16 Oct 2017 17:39:04 -0400 Received: from cock.li ([185.100.85.212]:43159) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e4D6B-0006j3-Hb for 28769@debbugs.gnu.org; Mon, 16 Oct 2017 17:39:02 -0400 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on cock.li X-Spam-Status: No, score=0.8 required=5.0 tests=BAYES_50 shortcircuit=_SCTYPE_ autolearn=disabled version=3.4.1 From: nee DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cock.li; s=mail; t=1508189933; bh=mQ+6uwAEfV62Q9tN3JE6LF9fWjZ31APE1+VuoAX08JU=; h=From:Subject:To:References:Cc:Date:In-Reply-To:From; b=CBxg11qqklOW87WlcoerKg09Cv8lffotp4l/C6ahO5CcbL96MvE4M+phXUYbRKUZz CszlassgMKVOJAYlESIzPceiq2giH2O2X4k2yKB34xEE4Z1kOcQhX4Mfvax9823TUl BVPZjr0uUZvldi/9ZvlK4FU/mQAVxfO14+wbPbmLsIVijn0AwOtHLQITMoa0bHRTnA 1D9sr/0DAcP6dFeHx4lzvMlVNiye3TxKS4YrTwQe+Q4OGwhKSaNHL8f4PaI6W2hAp9 P2O7otRXNLj66sMgWSTmkortbct+vTRE3PXHw13dJcrso6u9l8o4IWc26NgFsH41Ku DfzGw5Va6XyQA== Subject: Re: [bug#28769] [PATCH] gnu: services: Add php-fpm. To: Christopher Baines References: <9fe1701f-d78f-ba3a-37eb-64417337a55b@cock.li> <20171013223729.2605f33c@cbaines.net> Message-ID: <7462cec0-7d33-f2a3-1bd7-92454d690b0b@cock.li> Date: Mon, 16 Oct 2017 23:38:50 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.3.0 MIME-Version: 1.0 In-Reply-To: <20171013223729.2605f33c@cbaines.net> Content-Type: multipart/mixed; boundary="------------37973E72178760FF2FA1A3FB" Content-Language: en-GB X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 28769 Cc: 28769@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 0.0 (/) This is a multi-part message in MIME format. --------------37973E72178760FF2FA1A3FB Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit Hello, here is an updated version. I'm weirdly having trouble with getting the log-file to log something (see below), everything else should be addressed. Am 13.10.2017 um 23:37 schrieb Christopher Baines: > On Mon, 9 Oct 2017 23:54:24 +0200 > nee wrote: > >> Subject: [PATCH 2/2] gnu: services: Add php-fpm. > > Hey, I've never used php-fpm, but I'll have a go at reviewing this :) > >> * 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. > > Very minor, but I'd suggest "(Web Services): Document the php-fpm > service." here. > Okay, I changed the first letter to capital case and from the other patch 'function' to 'procedure'. >> --- >> 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 >> front-end as well. @end deftp >> >> >> +@cindex php-fpm >> +PHP-FPM (FastCGI Process Manager) is an alternative PHP FastCGI implementation >> +with some additional features useful for sites of any size. > > If these additional features are worth mentioning, it would be best to > be specific as to what they are, and what benefit they provide. > Okay I copied the list of features form the php-fpm homepage. I didn't add configuration for all of the features, tough. There is some advanced stuff with pools that use different php.inis, chroot, and using sendmail to email errors. I'm not much of a php user and I don't know how to test everything. I want to get a basic service working at first. >> +@defvr {Scheme Variable} php-fpm-service-type >> +A Service type for @code{php-fpm}. >> +@end defvr >> + > > ... > >> +@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-process-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 when type is @code{"dynamic"}. >> +@item @code {min-spare-servers} (default: @code{1}) >> +How many spare worker processes should be kept around at minimum. Only applies 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 applies 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. Only applies when type is @code{"ondemand"}. >> +@end table >> +@end deftp > > Reading this makes me think that maybe having record types per process > manager types might be useful, e.g. > > > > Good point! That makes misconfiguration less likely. I changed it to be that way. >> +@defvr {Scheme Variable} nginx-php-fpm-location >> +A helper function to quickly add php to an >> @code{nginx-server-configuration}. +@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)) > > The default-value for the service type means that you can omit the > (php-fpm-configuration) here, as (service php-fpm-service-type) should > work. > Okay, I changed the example. >> + (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 @@ >> >> 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)) > > When using other Guix services, I've run in to problems when field > accessors and record types were not exported. The biggest cost I can > think of is the lines of code, but I'd still suggest to export > everything by default here. > Okay, I export them now. The fcgiwrapper package does not export them though. That should be addressed in a separate patch later. >> ;;; Commentary: >> ;;; >> @@ -256,10 +266,12 @@ of index files." >> "events {}\n"))) >> >> (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") > > Pulling in your comment about the accounts... > >> 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. > > This sounds like it would work, however, the defaults for the > socket-user and socket-group of the php-fpm-configuration are currently > "nginx", which seems to disagree with what you say above? > That's a mistake. Seems like I actually forgot to change that. > Also, the idea that came to my mind for this is to add php-fpm as a > supplementary group for the nginx user. In my mind, this seems the > neatest way of giving nginx access to the socket. What do you think? > > I suggest this, as I'm not sure the name of the www-data group does a > good job of describing that it's controlling access to a socket. Also, > giving nginx explicit access to things owned by the php-fpm group could > be more secure than using a more generic group, especially as other > services that might need access to the socket, could end up getting it > because they need access to other things using the www-data group. > Using more specialized groups sounds good in general, I changed the group name. It would be weird to have the nginx user in a bunch of groups for software that you did not install though. > If the above sounds like a good idea, I think it could be implemented > by adding a configurable list of supplementary groups to the > nginx-service-type. Then maybe even adding support for configuring this > via the service extensions mechanism, then having the > php-fpm-service-type extending the nginx-service-type... > > The above is definitely to complicated to do all in one go, especially > since the nginx-service-type doesn't support anything more complicated > than adding server blocks through extension at the moment. > This seems to be a solution. >> @@ -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")) > > As above, I'm not sure the use of nginx here matches the > description you gave...? > Mistake on my side. I changed it to php-fpm now. >> + (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"))) > > I'm not sure the php is adding much to the log file name, but then > again I've never used php... what do you think? > For the workers-logfile: This is the logfile for the php workers error's It only logs errors that were printed with error_log by a php worker process. Try this example file: > + (file php-fpm-configuration-file ;#f | file-like >> + (default #f))) >> + >> +(define-record-type* >> php-fpm-process-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-children >> + (default 5)) >> + (start-servers >> php-fpm-process-manager-configuration-start-servers >> + (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-idle-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"))))))))) + > > As you can specify the user and group in the , I > think it might be better to just use the user and group names from > there, and always setup a user and group with those names, I'm guessing > that this will be what the average user would expect to happen. > I also thought that, but I took the config from the fastcgi service as example. The consequence of that is that you have to define your users yourself and get an error if you didn't. I'm changing it for this patch. >> +(define (default-php-fpm-config socket user group socket-user >> socket-group >> + 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 =" user "\n" >> + "group =" group "\n" >> + "listen =" socket "\n" >> + "listen.owner =" socket-user "\n" >> + "listen.group =" socket-group "\n" >> + >> + "pm =" pm.type "\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.process_idle_timeout =" (number->string >> pm.process-idle-timeout) "s\n" + >> + "php_flag[display_errors] = " (if display-errors "on" >> "off") "\n" + >> + (if workers-logfile >> + (list "catch_workers_output = yes\n" >> + "php_admin_value[error_log] =" workers-logfile >> "\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 >> + 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-errors >> + workers-logfile))))) >> + (stop #~(make-kill-destructor))))))) > > As php-fpm supports using a pid file, I'd recommend configuring both > php-fpm and shepherd to use this by default. It means that the shepherd > service will wait until php-fpm creates the PID file before starting > services that say they require it, which can prevent some issues. > I didn't know about this. It sounds like a good feature. I added it to the config and to the make-forkexec-constructor key now. Thanks for noting it! I also renamed the logfile variables to log-file to match the pid-file naming. >> +(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)))) > > Filling in the description (a relatively new field on the service type) > would be a great addition here. > Ah, yes I'm mostly using the web documentation and other services from web.scm as reference. Thanks for the update. What would be a good value for this field? I just used "The php-fpm service-type." for now. >> +(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." >> + (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;"))))) > > This helper seems good, although I think putting the "include" > elsewhere would be better, and I recognise that this isn't possible > with the nginx service yet. > Alright, so I'll keep it like this for now. > Overall, I think this is great. Excellent use of record types, gexps > and match expressions. I think it would be good to think more on the > accounts issue before merging, but that is all that comes to mind > currently. > Good to hear, thank you! :) > Also, if you feel like it, as service test would be a great addition to > this patch. There is a test for nginx already in gnu/tests/web.scm, and > I think you could get most of the benefit by having a test for nginx > with php-fpm, as that would give you some coverage over the php-fpm > service, as well as the nginx configuration. > That sounds great I love the idea of system tests and will have a look at it later. I also added a line to copyright headers of each file. Except for the utils.scm file, because that change is trivial copy pasta. Thank you for reviewing this very big patch. Happy hacking! --------------37973E72178760FF2FA1A3FB 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 894b6e3476bbf7c38427dd80438badba64830a98 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 procedure. --- 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 --------------37973E72178760FF2FA1A3FB 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 db872151028194b618af4ed652ea6934f10ce7ab 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 | 137 +++++++++++++++++++++++++++- gnu/services/web.scm | 248 +++++++++++++++++++++++++++++++++++++++++++++= +++++- 2 files changed, 382 insertions(+), 3 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index f0a59a6b4..280ab9930 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -40,7 +40,8 @@ Copyright @copyright{} 2017 Christopher Allan Webber@* Copyright @copyright{} 2017 Marius Bakke@* Copyright @copyright{} 2017 Hartmut Goebel@* Copyright @copyright{} 2017 Maxim Cournoyer@* -Copyright @copyright{} 2017 Tobias Geerinckx-Rice +Copyright @copyright{} 2017 Tobias Geerinckx-Rice@* +Copyright @copyright{} 2017 nee =20 Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or @@ -14529,6 +14530,140 @@ capability also has to be configured on the fro= nt-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. + +These features include: +@itemize @bullet +@item Adaptive process spawning +@item Basic statistics (ala Apache's mod_status) +@item Advanced process management with graceful stop/start +@item Ability to start workers with different uid/gid/chroot/environment= +and different php.ini (replaces safe_mode) +@item Stdout & stderr logging +@item Emergency restart in case of accidental opcode cache destruction +@item Accelerated upload support +@item Support for a "slowlog" +@item Enhancements to FastCGI, such as fastcgi_finish_request() - +a special function to finish request & flush all data while continuing t= o do +something time-consuming (video converting, stats processing, etc.) +@end itemize +... and much more. + +@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{php-fpm}) +User who can speak to the php-fpm socket. +@item @code {socket-group} (default: @code{php-fpm}) +Group that can speak to the php-fpm socket. +@item @code {pid-file} (default: @code{(string-append "/var/log/php" (ve= rsion-major (package-version php)) "-fpm.pid")}) +The process id of the php-fpm process is written to this file +once the service has started. +@item @code {log-file} (default: @code{(string-append "/var/log/php" (ve= rsion-major (package-version php)) "-fpm.log")}) +Log for the php-fpm master process. +@item @code {process-manager} (default: @code{(php-fpm-dynamic-process-m= anager-configuration)}) +Detailed settings for the php-fpm process manager. +Must be either: +@table @asis +@item @code{} +@item @code{} +@item @code{} +@end table +@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.www.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-dynamic-process-manager-configuration +Data Type for the @code{dynamic} php-fpm process manager. +With the @code{dynamic} process manager spare worker processes are kept = around +based on it's configured limits. +@table @asis +@item @code {max-children} (default: @code{5}) +Maximum of worker processes. +@item @code {start-servers} (default: @code{2}) +How many worker processes should be started on start-up. +@item @code {min-spare-servers} (default: @code{1}) +How many spare worker processes should be kept around at minimum. +@item @code {max-spare-servers} (default: @code{3}) +How many spare worker processes should be kept around at maximum. +@end table +@end deftp + +@deftp {Data type} php-fpm-static-process-manager-configuration +Data Type for the @code{static} php-fpm process manager. +With the @code{static} process manager an unchanging number +of worker processes is created. +@table @asis +@item @code {max-children} (default: @code{5}) +Maximum of worker processes. +@end table +@end deftp + +@deftp {Data type} php-fpm-on-demand-process-manager-configuration +Data Type for the @code{on-demand} php-fpm process manager. +With the @code{on-demand} process manager worker processes are only crea= ted +as requests arrive. +@table @asis +@item @code {max-children} (default: @code{5}) +Maximum of worker processes. +@item @code {process-idle-timeout} (default: @code{10}) +The time in seconds after which a process with no requests is killed. +@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) + (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..ef51f4a55 100644 --- a/gnu/services/web.scm +++ b/gnu/services/web.scm @@ -4,6 +4,7 @@ ;;; Copyright =C2=A9 2016 ng0 ;;; Copyright =C2=A9 2016, 2017 Julien Lepiller ;;; Copyright =C2=A9 2017 Christopher Baines +;;; Copyright =C2=A9 2017 nee ;;; ;;; This file is part of GNU Guix. ;;; @@ -26,8 +27,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 +80,49 @@ =20 fcgiwrap-configuration fcgiwrap-configuration? - fcgiwrap-service-type)) + 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-workers-log-file + php-fpm-configuration-file + =20 + + 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-serv= ers + php-fpm-dynamic-process-manager-configuration-max-spare-serv= ers + =20 + + 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 + =20 + + 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)) =20 ;;; Commentary: ;;; @@ -256,10 +302,12 @@ of index files." "events {}\n"))) =20 (define %nginx-accounts - (list (user-group (name "nginx") (system? #t)) + (list (user-group (name "php-fpm") (system? #t)) + (user-group (name "nginx") (system? #t)) (user-account (name "nginx") (group "nginx") + (supplementary-groups '("php-fpm")) (system? #t) (comment "nginx server user") (home-directory "/var/empty") @@ -385,3 +433,199 @@ 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-vers= ion 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 "php-fpm")) + (pid-file php-fpm-configuration-pid-file + (default (string-append "/var/run/php" + (version-major (package-vers= ion php)) + "-fpm.pid"))) + (log-file php-fpm-configuration-log-file + (default (string-append "/var/log/php" + (version-major (package-vers= ion php)) + "-fpm.log"))) + (process-manager php-fpm-configuration-process-manager + (default (php-fpm-dynamic-process-manager-configurat= ion))) + (display-errors php-fpm-configuration-display-errors + (default #f)) + (workers-log-file php-fpm-configuration-workers-log-file + (default (string-append "/var/log/php" + (version-major (package-vers= ion php)) + "-fpm.www.log"))) + (file php-fpm-configuration-file ;#f | file-like + (default #f))) + +(define-record-type* + php-fpm-dynamic-process-manager-configuration + make-php-fpm-dynamic-process-manager-configuration + php-fpm-dynamic-process-manager-configuration? + (max-children php-fpm-dynamic-process-manager-configuration-ma= x-children + (default 5)) + (start-servers php-fpm-dynamic-process-manager-configuration-st= art-servers + (default 2)) + (min-spare-servers php-fpm-dynamic-process-manager-configuration-mi= n-spare-servers + (default 1)) + (max-spare-servers php-fpm-dynamic-process-manager-configuration-ma= x-spare-servers + (default 3))) + +(define-record-type* + php-fpm-static-process-manager-configuration + make-php-fpm-static-process-manager-configuration + php-fpm-static-process-manager-configuration? + (max-children php-fpm-static-process-manager-configuration-max= -children + (default 5))) + +(define-record-type* + php-fpm-on-demand-process-manager-configuration + make-php-fpm-on-demand-process-manager-configuration + php-fpm-on-demand-process-manager-configuration? + (max-children php-fpm-on-demand-process-manager-configuration-= max-children + (default 5)) + (process-idle-timeout php-fpm-on-demand-process-manager-configuration-= process-idle-timeout + (default 10))) + +(define php-fpm-accounts + (match-lambda + (($ php socket user group socket-user socket= -group _ _ _ _ _ _) + (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"))))))) + +(define (default-php-fpm-config socket user group socket-user socket-gro= up + pid-file log-file pm display-errors workers-log-file) + (apply mixed-text-file "php-fpm.conf" + (flatten + "[global]\n" + "pid =3D" pid-file "\n" + "error_log =3D" log-file "\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" + + (match pm + (($ + pm.max-children + pm.start-servers + pm.min-spare-servers + pm.max-spare-servers) + (list + "pm =3D dynamic\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-se= rvers) "\n" + "pm.max_spare_servers =3D" (number->string pm.max-spare-se= rvers) "\n")) + =20 + (($ + pm.max-children) + (list + "pm =3D static\n" + "pm.max_children =3D" (number->string pm.max-children) "\n= ")) + =20 + (($ + pm.max-children + pm.process-idle-timeout) + (list + "pm =3D ondemand\n" + "pm.max_children =3D" (number->string pm.max-children) "\n= " + "pm.process_idle_timeout =3D" (number->string pm.process-i= dle-timeout) "s\n"))) + + + "php_flag[display_errors] =3D " (if display-errors "on" "off")= "\n" + + (if workers-log-file + (list "catch_workers_output =3D yes\n" + "php_admin_value[error_log] =3D" workers-log-file "\= 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 + pid-file log-file pm display-errors work= ers-log-file 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 pid-file log-fi= le + pm display-errors workers-log-file))) + #:pid-file #$pid-file)) + (stop #~(make-kill-destructor))))))) + +(define php-fpm-activation + (match-lambda + (($ _ _ user _ _ _ _ log-file _ _ workers-lo= g-file _) + #~(begin + (use-modules (guix build utils)) + (let* ((user (getpwnam #$user)) + (touch (lambda (file-name) + (call-with-output-file file-name (const #t)))) + (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 #$log-file) + (init-log-file #$workers-log-file)))))) + + +(define php-fpm-service-type + (service-type (name 'php-fpm) + (description "The php-fpm service-type.") + (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 --------------37973E72178760FF2FA1A3FB-- From debbugs-submit-bounces@debbugs.gnu.org Mon Oct 23 18:26:50 2017 Received: (at 28769) by debbugs.gnu.org; 23 Oct 2017 22:26:50 +0000 Received: from localhost ([127.0.0.1]:58110 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e6lBJ-0001hc-74 for submit@debbugs.gnu.org; Mon, 23 Oct 2017 18:26:49 -0400 Received: from cock.li ([185.100.85.212]:40344) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e6lBF-0001hN-Nc for 28769@debbugs.gnu.org; Mon, 23 Oct 2017 18:26:47 -0400 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on cock.li X-Spam-Status: No, score=-0.0 required=5.0 tests=BAYES_20 shortcircuit=_SCTYPE_ autolearn=disabled version=3.4.1 Subject: Re: [bug#28769] [PATCH] gnu: services: Add php-fpm. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cock.li; s=mail; t=1508797599; bh=zKhbe32TJ5e5jdTLryBvOt2crLA6UH6Wooh9KAPrfwY=; h=Subject:To:References:From:Date:In-Reply-To:From; b=bjHBXbXlnE5/Dgq7XssAYnhDerprkqPFMJJTvrD2uwZ5+hCOUT+Mypufjy6awH0Qb p6lVhncmGYKJebHUDFbDNChPK2MExSUzAKhIYBQ/jONIciTnSleacfznMHQol0XSOv 40wJnla2j0Mlu4uWebcijYP5hN2oiItKqwAMJh3khSq54Z/5633tga+5h9e4TfCK8g xy6TKl0JyIVc1DIEwNApzs3QnKkr9egQbPqauMQSRM+tcGix+ZLkEp1tQAkq40D7KA RdYvUKxxD+0gN9l+2u2xVr0xhbFl3//UqSX1+amry/rtkrGDB1BOGjMXgGhf7GCgtD WkyoPuWfJxWaA== To: Christopher Baines , 28769@debbugs.gnu.org References: <9fe1701f-d78f-ba3a-37eb-64417337a55b@cock.li> <20171013223729.2605f33c@cbaines.net> <7462cec0-7d33-f2a3-1bd7-92454d690b0b@cock.li> From: nee Message-ID: <13db8f5b-4add-8a22-05a3-7bfb577adc69@cock.li> Date: Tue, 24 Oct 2017 00:26:35 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.3.0 MIME-Version: 1.0 In-Reply-To: <7462cec0-7d33-f2a3-1bd7-92454d690b0b@cock.li> Content-Type: multipart/mixed; boundary="------------2EC96FC184ED0DA9D04BE9BC" Content-Language: en-GB X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 28769 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 0.0 (/) This is a multi-part message in MIME format. --------------2EC96FC184ED0DA9D04BE9BC Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit Hello again, I fixed the empty log-file. Here are the updated patches. The problem was this line: >+ "--nodaemonize" "-p" "/var" "--fpm-config" When --nodaemonize is set, the log is printed to stdout instead. I also removed -p "/var". It is not required when the log, pid and socket locations are defined in the config. Both were caused, because I didn't use pid-files from the start. Happy Hacking! --------------2EC96FC184ED0DA9D04BE9BC 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 894b6e3476bbf7c38427dd80438badba64830a98 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 procedure. --- 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 --------------2EC96FC184ED0DA9D04BE9BC 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 62d1d7627e8a83015abfc9d055a44333dfa0d46e 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 | 137 +++++++++++++++++++++++++++- gnu/services/web.scm | 248 +++++++++++++++++++++++++++++++++++++++++++++= +++++- 2 files changed, 382 insertions(+), 3 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index f0a59a6b4..280ab9930 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -40,7 +40,8 @@ Copyright @copyright{} 2017 Christopher Allan Webber@* Copyright @copyright{} 2017 Marius Bakke@* Copyright @copyright{} 2017 Hartmut Goebel@* Copyright @copyright{} 2017 Maxim Cournoyer@* -Copyright @copyright{} 2017 Tobias Geerinckx-Rice +Copyright @copyright{} 2017 Tobias Geerinckx-Rice@* +Copyright @copyright{} 2017 nee =20 Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or @@ -14529,6 +14530,140 @@ capability also has to be configured on the fro= nt-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. + +These features include: +@itemize @bullet +@item Adaptive process spawning +@item Basic statistics (ala Apache's mod_status) +@item Advanced process management with graceful stop/start +@item Ability to start workers with different uid/gid/chroot/environment= +and different php.ini (replaces safe_mode) +@item Stdout & stderr logging +@item Emergency restart in case of accidental opcode cache destruction +@item Accelerated upload support +@item Support for a "slowlog" +@item Enhancements to FastCGI, such as fastcgi_finish_request() - +a special function to finish request & flush all data while continuing t= o do +something time-consuming (video converting, stats processing, etc.) +@end itemize +... and much more. + +@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{php-fpm}) +User who can speak to the php-fpm socket. +@item @code {socket-group} (default: @code{php-fpm}) +Group that can speak to the php-fpm socket. +@item @code {pid-file} (default: @code{(string-append "/var/log/php" (ve= rsion-major (package-version php)) "-fpm.pid")}) +The process id of the php-fpm process is written to this file +once the service has started. +@item @code {log-file} (default: @code{(string-append "/var/log/php" (ve= rsion-major (package-version php)) "-fpm.log")}) +Log for the php-fpm master process. +@item @code {process-manager} (default: @code{(php-fpm-dynamic-process-m= anager-configuration)}) +Detailed settings for the php-fpm process manager. +Must be either: +@table @asis +@item @code{} +@item @code{} +@item @code{} +@end table +@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.www.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-dynamic-process-manager-configuration +Data Type for the @code{dynamic} php-fpm process manager. +With the @code{dynamic} process manager spare worker processes are kept = around +based on it's configured limits. +@table @asis +@item @code {max-children} (default: @code{5}) +Maximum of worker processes. +@item @code {start-servers} (default: @code{2}) +How many worker processes should be started on start-up. +@item @code {min-spare-servers} (default: @code{1}) +How many spare worker processes should be kept around at minimum. +@item @code {max-spare-servers} (default: @code{3}) +How many spare worker processes should be kept around at maximum. +@end table +@end deftp + +@deftp {Data type} php-fpm-static-process-manager-configuration +Data Type for the @code{static} php-fpm process manager. +With the @code{static} process manager an unchanging number +of worker processes is created. +@table @asis +@item @code {max-children} (default: @code{5}) +Maximum of worker processes. +@end table +@end deftp + +@deftp {Data type} php-fpm-on-demand-process-manager-configuration +Data Type for the @code{on-demand} php-fpm process manager. +With the @code{on-demand} process manager worker processes are only crea= ted +as requests arrive. +@table @asis +@item @code {max-children} (default: @code{5}) +Maximum of worker processes. +@item @code {process-idle-timeout} (default: @code{10}) +The time in seconds after which a process with no requests is killed. +@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) + (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..d30f3af2a 100644 --- a/gnu/services/web.scm +++ b/gnu/services/web.scm @@ -4,6 +4,7 @@ ;;; Copyright =C2=A9 2016 ng0 ;;; Copyright =C2=A9 2016, 2017 Julien Lepiller ;;; Copyright =C2=A9 2017 Christopher Baines +;;; Copyright =C2=A9 2017 nee ;;; ;;; This file is part of GNU Guix. ;;; @@ -26,8 +27,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 +80,49 @@ =20 fcgiwrap-configuration fcgiwrap-configuration? - fcgiwrap-service-type)) + 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-workers-log-file + php-fpm-configuration-file + =20 + + 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-serv= ers + php-fpm-dynamic-process-manager-configuration-max-spare-serv= ers + =20 + + 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 + =20 + + 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)) =20 ;;; Commentary: ;;; @@ -256,10 +302,12 @@ of index files." "events {}\n"))) =20 (define %nginx-accounts - (list (user-group (name "nginx") (system? #t)) + (list (user-group (name "php-fpm") (system? #t)) + (user-group (name "nginx") (system? #t)) (user-account (name "nginx") (group "nginx") + (supplementary-groups '("php-fpm")) (system? #t) (comment "nginx server user") (home-directory "/var/empty") @@ -385,3 +433,199 @@ 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-vers= ion 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 "php-fpm")) + (pid-file php-fpm-configuration-pid-file + (default (string-append "/var/run/php" + (version-major (package-vers= ion php)) + "-fpm.pid"))) + (log-file php-fpm-configuration-log-file + (default (string-append "/var/log/php" + (version-major (package-vers= ion php)) + "-fpm.log"))) + (process-manager php-fpm-configuration-process-manager + (default (php-fpm-dynamic-process-manager-configurat= ion))) + (display-errors php-fpm-configuration-display-errors + (default #f)) + (workers-log-file php-fpm-configuration-workers-log-file + (default (string-append "/var/log/php" + (version-major (package-vers= ion php)) + "-fpm.www.log"))) + (file php-fpm-configuration-file ;#f | file-like + (default #f))) + +(define-record-type* + php-fpm-dynamic-process-manager-configuration + make-php-fpm-dynamic-process-manager-configuration + php-fpm-dynamic-process-manager-configuration? + (max-children php-fpm-dynamic-process-manager-configuration-ma= x-children + (default 5)) + (start-servers php-fpm-dynamic-process-manager-configuration-st= art-servers + (default 2)) + (min-spare-servers php-fpm-dynamic-process-manager-configuration-mi= n-spare-servers + (default 1)) + (max-spare-servers php-fpm-dynamic-process-manager-configuration-ma= x-spare-servers + (default 3))) + +(define-record-type* + php-fpm-static-process-manager-configuration + make-php-fpm-static-process-manager-configuration + php-fpm-static-process-manager-configuration? + (max-children php-fpm-static-process-manager-configuration-max= -children + (default 5))) + +(define-record-type* + php-fpm-on-demand-process-manager-configuration + make-php-fpm-on-demand-process-manager-configuration + php-fpm-on-demand-process-manager-configuration? + (max-children php-fpm-on-demand-process-manager-configuration-= max-children + (default 5)) + (process-idle-timeout php-fpm-on-demand-process-manager-configuration-= process-idle-timeout + (default 10))) + +(define php-fpm-accounts + (match-lambda + (($ php socket user group socket-user socket= -group _ _ _ _ _ _) + (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"))))))) + +(define (default-php-fpm-config socket user group socket-user socket-gro= up + pid-file log-file pm display-errors workers-log-file) + (apply mixed-text-file "php-fpm.conf" + (flatten + "[global]\n" + "pid =3D" pid-file "\n" + "error_log =3D" log-file "\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" + + (match pm + (($ + pm.max-children + pm.start-servers + pm.min-spare-servers + pm.max-spare-servers) + (list + "pm =3D dynamic\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-se= rvers) "\n" + "pm.max_spare_servers =3D" (number->string pm.max-spare-se= rvers) "\n")) + =20 + (($ + pm.max-children) + (list + "pm =3D static\n" + "pm.max_children =3D" (number->string pm.max-children) "\n= ")) + =20 + (($ + pm.max-children + pm.process-idle-timeout) + (list + "pm =3D ondemand\n" + "pm.max_children =3D" (number->string pm.max-children) "\n= " + "pm.process_idle_timeout =3D" (number->string pm.process-i= dle-timeout) "s\n"))) + + + "php_flag[display_errors] =3D " (if display-errors "on" "off")= "\n" + + (if workers-log-file + (list "catch_workers_output =3D yes\n" + "php_admin_value[error_log] =3D" workers-log-file "\= 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 + pid-file log-file pm display-errors work= ers-log-file 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") + "--fpm-config" + #$(or file + (default-php-fpm-config socket user group + socket-user socket-group pid-file log-fi= le + pm display-errors workers-log-file))) + #:pid-file #$pid-file)) + (stop #~(make-kill-destructor))))))) + +(define php-fpm-activation + (match-lambda + (($ _ _ user _ _ _ _ log-file _ _ workers-lo= g-file _) + #~(begin + (use-modules (guix build utils)) + (let* ((user (getpwnam #$user)) + (touch (lambda (file-name) + (call-with-output-file file-name (const #t)))) + (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 #$log-file) + (init-log-file #$workers-log-file)))))) + + +(define php-fpm-service-type + (service-type (name 'php-fpm) + (description "The php-fpm service-type.") + (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 --------------2EC96FC184ED0DA9D04BE9BC-- From debbugs-submit-bounces@debbugs.gnu.org Thu Nov 02 04:16:50 2017 Received: (at 28769) by debbugs.gnu.org; 2 Nov 2017 08:16:50 +0000 Received: from localhost ([127.0.0.1]:46814 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eAAgC-0002Pj-Bm for submit@debbugs.gnu.org; Thu, 02 Nov 2017 04:16:48 -0400 Received: from li622-129.members.linode.com ([212.71.249.129]:39390 helo=mira.cbaines.net) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eAAg7-0002PY-DP for 28769@debbugs.gnu.org; Thu, 02 Nov 2017 04:16:44 -0400 Received: by mira.cbaines.net (Postfix, from userid 113) id B6F7913E799; Thu, 2 Nov 2017 08:16:42 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00, T_FRT_COCK,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from localhost (cpc102582-walt20-2-0-cust14.13-2.cable.virginm.net [86.27.34.15]) by mira.cbaines.net (Postfix) with ESMTPSA id CCE4513E6E6; Thu, 2 Nov 2017 08:16:41 +0000 (GMT) Date: Thu, 2 Nov 2017 08:16:38 +0000 From: Christopher Baines To: nee Subject: Re: [bug#28769] [PATCH] gnu: services: Add php-fpm. Message-ID: <20171102081638.3428206f@cbaines.net> In-Reply-To: <13db8f5b-4add-8a22-05a3-7bfb577adc69@cock.li> References: <9fe1701f-d78f-ba3a-37eb-64417337a55b@cock.li> <20171013223729.2605f33c@cbaines.net> <7462cec0-7d33-f2a3-1bd7-92454d690b0b@cock.li> <13db8f5b-4add-8a22-05a3-7bfb577adc69@cock.li> X-Mailer: Claws Mail 3.15.1-dirty (GTK+ 2.24.31; x86_64-unknown-linux-gnu) MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; boundary="Sig_/rhy0/IOCpFBBYhJI0Me39r+"; protocol="application/pgp-signature" X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 28769 Cc: 28769@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) --Sig_/rhy0/IOCpFBBYhJI0Me39r+ Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable On Tue, 24 Oct 2017 00:26:35 +0200 nee wrote: > Hello again, > I fixed the empty log-file. Here are the updated patches. >=20 > The problem was this line: > >+ "--nodaemonize" "-p" "/var" "--fpm-config" =20 >=20 > When --nodaemonize is set, the log is printed to stdout instead. > I also removed -p "/var". It is not required when the log, pid and > socket locations are defined in the config. > Both were caused, because I didn't use pid-files from the start. >=20 > Happy Hacking! Hey, Just wanted to say I've started looking at this again, I'll hopefully get around to replying later today, or tomorrow. Chris --Sig_/rhy0/IOCpFBBYhJI0Me39r+ Content-Type: application/pgp-signature Content-Description: OpenPGP digital signature -----BEGIN PGP SIGNATURE----- iQKTBAEBCgB9FiEEPonu50WOcg2XVOCyXiijOwuE9XcFAln61GZfFIAAAAAALgAo aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldDNF ODlFRUU3NDU4RTcyMEQ5NzU0RTBCMjVFMjhBMzNCMEI4NEY1NzcACgkQXiijOwuE 9Xc2kw//cNZJ+k30XB4BjwYyo3+IeEJbpmzu1qziALkhUILB6W8XOts6tIa+xDCU TVCxGHfPn7pTI/95vP3vPeew/FwcHumjkfx/8oXBFzN0dgMb/aqLB34mNaPj+5CB YrDJBguel4bmh/UbEpcLdcRXtD0ngQnUuPhBjFq70ksaVNkDnIpKUNUKS0H/lc6W 2MknuWsfig5oNxG78gxjJlEgRq/p1O7yg/N1VerkDn667ErVjO4pNmFTE/A6MYkt SFXNWMq1roWautOcB5D9Vl9AwGfNaeiyfsOTM/BQB+lfASBdvqIbGohYY6b/xYVL uPUD6gtgzZKk2YNOGjgxgBR4MKO6qiNKCfziQT/B1lOfTjyNqKRe14OSeWWfRrbE O2PZeA4Kp1VL1rt3I8czhvyvNmnZ0NBEKzDBHrI5y2kV5QNM34TJpC0x4MH1dLmg KzW0WrVgFCR6qRaZbnX+DJgSDx7FgQwl+KPBCK37xLwup202znKYeElnVX3ecOz7 uXCsGquPjO5GN9I+x4zrHgGS+G/worYNgEWQZ9Thi5VjQx75Zg7oWKiEVX1yaXgi bL03t93U77E2wBRZKqwEuSIH8mml/ciJY3dgywQ1gK6CJbjzWumeDGe1lxYfgCVw D7X7K1FPsFGFeGwMoMZwDCV9tZlKVQNJIv+ZvejYET/Se8AlShU= =LWgc -----END PGP SIGNATURE----- --Sig_/rhy0/IOCpFBBYhJI0Me39r+-- From debbugs-submit-bounces@debbugs.gnu.org Thu Nov 02 15:17:17 2017 Received: (at 28769) by debbugs.gnu.org; 2 Nov 2017 19:17:17 +0000 Received: from localhost ([127.0.0.1]:48272 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eAKzM-0005O9-Qo for submit@debbugs.gnu.org; Thu, 02 Nov 2017 15:17:17 -0400 Received: from li622-129.members.linode.com ([212.71.249.129]:39765 helo=mira.cbaines.net) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eAKzK-0005O0-Of for 28769@debbugs.gnu.org; Thu, 02 Nov 2017 15:17:15 -0400 Received: by mira.cbaines.net (Postfix, from userid 113) id 24F9013E7A0; Thu, 2 Nov 2017 19:17:14 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00, T_FRT_COCK,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from localhost (cpc102582-walt20-2-0-cust14.13-2.cable.virginm.net [86.27.34.15]) by mira.cbaines.net (Postfix) with ESMTPSA id 342B813E79E; Thu, 2 Nov 2017 19:17:12 +0000 (GMT) Date: Thu, 2 Nov 2017 19:17:08 +0000 From: Christopher Baines To: nee Subject: Re: [bug#28769] [PATCH] gnu: services: Add php-fpm. Message-ID: <20171102191708.0cf85810@cbaines.net> In-Reply-To: <7462cec0-7d33-f2a3-1bd7-92454d690b0b@cock.li> References: <9fe1701f-d78f-ba3a-37eb-64417337a55b@cock.li> <20171013223729.2605f33c@cbaines.net> <7462cec0-7d33-f2a3-1bd7-92454d690b0b@cock.li> X-Mailer: Claws Mail 3.15.1-dirty (GTK+ 2.24.31; x86_64-unknown-linux-gnu) MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; boundary="Sig_/KViE2HtsC71FhzZ_pYG4OFd"; protocol="application/pgp-signature" X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 28769 Cc: 28769@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) --Sig_/KViE2HtsC71FhzZ_pYG4OFd Content-Type: multipart/mixed; boundary="MP_/TvWRodwxy3TnNo5jMlnjt6B" --MP_/TvWRodwxy3TnNo5jMlnjt6B Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline On Mon, 16 Oct 2017 23:38:50 +0200 nee wrote: I've also read your subsequent message about fixing the log files, but I'll reply here, as there is more to reply to. > Hello, here is an updated version. ... > > Also, the idea that came to my mind for this is to add php-fpm as a > > supplementary group for the nginx user. In my mind, this seems the > > neatest way of giving nginx access to the socket. What do you think? > >=20 > > I suggest this, as I'm not sure the name of the www-data group does a > > good job of describing that it's controlling access to a socket. Also, > > giving nginx explicit access to things owned by the php-fpm group could > > be more secure than using a more generic group, especially as other > > services that might need access to the socket, could end up getting it > > because they need access to other things using the www-data group. > > =20 > Using more specialized groups sounds good in general, I changed the > group name. > It would be weird to have the nginx user in a bunch of groups for > software that you did not install though. > > If the above sounds like a good idea, I think it could be implemented > > by adding a configurable list of supplementary groups to the > > nginx-service-type. Then maybe even adding support for configuring this > > via the service extensions mechanism, then having the > > php-fpm-service-type extending the nginx-service-type... > >=20 > > The above is definitely to complicated to do all in one go, especially > > since the nginx-service-type doesn't support anything more complicated > > than adding server blocks through extension at the moment. > > =20 > This seems to be a solution. I've now attached a system test for php-fpm, that sets it up with nginx, creates a basic php file, and checks that it can be requested. This seems to work, which I was a little surprised at, as I was suspecting problems with the socket permissions. I had a look, and while the nginx workers in the test system are not root, the nginx master process is, so maybe that allows it to work... Anyway, providing that the test reflects how the service might be used, it seems like this is a non-issue for now. > >> @@ -385,3 +397,160 @@ of index files." > >> (service-extension account-service-type > >> fcgiwrap-accounts))) > >> (default-value (fcgiwrap-configuration)))) ... > >> + (version-major > >> (package-version php)) > >> + "-fpm.log"))) =20 > >=20 > > I'm not sure the php is adding much to the log file name, but then > > again I've never used php... what do you think? > > =20 > For the workers-logfile: > This is the logfile for the php workers error's > It only logs errors that were printed with error_log by a php worker > process. > Try this example file: >=20 > error_log("some error\n"); // should be in the log > echo "Hello from php"; // should be in the browser >=20 > Then visit the err.php file with curl or a browser using the nginx > example above. >=20 > Also: > I forgot to add a setting for the log-file of the php-fpm master > process. This file should log messages when php-fpm has started or stoppe= d. >=20 > For some reason it stays empty now. I had it log stuff before, when I > manually killed the process, but I can't reproduce it anymore. I changed > the permissions to ugo+wrx and it still stays empty. I'm not sure what's > going on. >=20 > I renamed the default workers-log-file to php7-fpm.www.log as it is > usually called. The php-fpm log-file is now called php7-fpm.log. What I think I meant to say here was, I'm not sure the php _version_ is adding much to the log file name (rather than "I'm not sure the php is adding"). The php package version is used in a few places, and while I can imagine this being consistent with other distributions, it does add a bit of complexity to the default values in the service, and I'm not sure what benefit it brings? > >> + (file php-fpm-configuration-file ;#f | file-like > >> + (default #f))) ... > >> + (service-extension account-service-type > >> + php-fpm-accounts))) > >> + (default-value (php-fpm-configuration)))) =20 > >=20 > > Filling in the description (a relatively new field on the service type) > > would be a great addition here. > > =20 > Ah, yes I'm mostly using the web documentation and other services from > web.scm as reference. Thanks for the update. > What would be a good value for this field? I just used "The php-fpm > service-type." for now. That is ok, but it could probably be more useful. I think ideally it would describe more about what the service offers. Users might encounter this when searching for services for example: =E2=86=92 guix system search php name: php-fpm location: gnu/services/web.scm:607:2 extends: shepherd-root activate account description: The php-fpm service-type. relevance: 5 > >> +(define* (nginx-php-location > >> + #:key > >> + (nginx-package nginx) ... > > Overall, I think this is great. Excellent use of record types, gexps > > and match expressions. I think it would be good to think more on the > > accounts issue before merging, but that is all that comes to mind > > currently. > > =20 > Good to hear, thank you! :) >=20 > > Also, if you feel like it, as service test would be a great addition to > > this patch. There is a test for nginx already in gnu/tests/web.scm, and > > I think you could get most of the benefit by having a test for nginx > > with php-fpm, as that would give you some coverage over the php-fpm > > service, as well as the nginx configuration. > > =20 > That sounds great I love the idea of system tests and will have a look > at it later. >=20 > I also added a line to copyright headers of each file. Except for the > utils.scm file, because that change is trivial copy pasta. I've attached a patch containing a couple of copy+paste fixes, and a system test. It would be good to get your opinion on the system test, does it test the right things? If you like the look of it, I'd suggest including those changes in the commit that adds the service, and then sending the updated patches. I've included a changelog in the commit message. Now that there is a system test, and the php-fpm service seems to work fine with the nginx service, I think that means that doing anything extra with accounts can be done later. --MP_/TvWRodwxy3TnNo5jMlnjt6B Content-Type: text/x-patch Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename=0001-Add-fixes-and-system-test-for-PHP-FPM.patch =46rom cb37c6e0353cebcdab81280a15d618e8b3ccd631 Mon Sep 17 00:00:00 2001 From: Christopher Baines Date: Thu, 2 Nov 2017 18:39:21 +0000 Subject: [PATCH] Add fixes and system test for PHP-FPM Probably best to fixup this in to the commit that adds the service. * gnu/tests/web.scm (%make-php-fpm-http-root, %php-fpm-nginx-server-blocks, %php-fpm-os, %test-php-fpm): New variables. (run-php-fpm-test): New procedure. --- gnu/services/web.scm | 4 +- gnu/tests/web.scm | 109 +++++++++++++++++++++++++++++++++++++++++++++++= +++- 2 files changed, 110 insertions(+), 3 deletions(-) diff --git a/gnu/services/web.scm b/gnu/services/web.scm index d30f3af2a..168c23cce 100644 --- a/gnu/services/web.scm +++ b/gnu/services/web.scm @@ -114,7 +114,7 @@ php-fpm-static-process-manager-configuration? php-fpm-static-process-manager-configuration-max-children =20 - + php-fpm-on-demand-process-manager-configuration make-php-fpm-on-demand-process-manager-configuration php-fpm-on-demand-process-manager-configuration? @@ -490,7 +490,7 @@ of index files." (max-children php-fpm-static-process-manager-configuration-max-c= hildren (default 5))) =20 -(define-record-type* +(define-record-type* php-fpm-on-demand-process-manager-configuration make-php-fpm-on-demand-process-manager-configuration php-fpm-on-demand-process-manager-configuration? diff --git a/gnu/tests/web.scm b/gnu/tests/web.scm index 3fa272c67..bf8435711 100644 --- a/gnu/tests/web.scm +++ b/gnu/tests/web.scm @@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright =C2=A9 2017 Ludovic Court=C3=A8s +;;; Copyright =C2=A9 2017 Christopher Baines ;;; ;;; This file is part of GNU Guix. ;;; @@ -27,7 +28,8 @@ #:use-module (gnu services networking) #:use-module (guix gexp) #:use-module (guix store) - #:export (%test-nginx)) + #:export (%test-nginx + %test-php-fpm)) =20 (define %index.html-contents ;; Contents of the /index.html file served by nginx. @@ -132,3 +134,108 @@ HTTP-PORT." (name "nginx") (description "Connect to a running NGINX server.") (value (run-nginx-test)))) + +=0C +;;; +;;; PHP-FPM +;;; + +(define %make-php-fpm-http-root + ;; Create our server root in /srv. + #~(begin + (mkdir "/srv") + (call-with-output-file "/srv/index.php" + (lambda (port) + (display "\n" port))))) + +(define %php-fpm-nginx-server-blocks + (list (nginx-server-configuration + (root "/srv") + (locations + (list (nginx-php-location))) + (http-port 8042) + (https-port #f) + (ssl-certificate #f) + (ssl-certificate-key #f)))) + +(define %php-fpm-os + ;; Operating system under test. + (simple-operating-system + (dhcp-client-service) + (service php-fpm-service-type) + (service nginx-service-type + (nginx-configuration + (server-blocks %php-fpm-nginx-server-blocks))) + (simple-service 'make-http-root activation-service-type + %make-php-fpm-http-root))) + +(define* (run-php-fpm-test #:optional (http-port 8042)) + "Run tests in %PHP-FPM-OS, which has nginx running and listening on +HTTP-PORT, along with php-fpm." + (define os + (marionette-operating-system + %php-fpm-os + #:imported-modules '((gnu services herd) + (guix combinators)))) + + (define vm + (virtual-machine + (operating-system os) + (port-forwardings `((8080 . ,http-port))))) + + (define test + (with-imported-modules '((gnu build marionette) + (guix build utils)) + #~(begin + (use-modules (srfi srfi-11) (srfi srfi-64) + (gnu build marionette) + (web uri) + (web client) + (web response)) + + (define marionette + (make-marionette (list #$vm))) + + (mkdir #$output) + (chdir #$output) + + (test-begin "php-fpm") + + (test-assert "php-fpm running" + (marionette-eval + '(begin + (use-modules (gnu services herd)) + (match (start-service 'php-fpm) + (#f #f) + (('service response-parts ...) + (match (assq-ref response-parts 'running) + ((pid) (number? pid)))))) + marionette)) + + (test-eq "nginx running" + 'running! + (marionette-eval + '(begin + (use-modules (gnu services herd)) + (start-service 'nginx) + 'running!) + marionette)) + + (test-equal "http-get" + 200 + (let-values (((response text) + (http-get "http://localhost:8080/index.php" + #:decode-body? #t))) + (response-code response))) + + (test-end) + =20 + (exit (=3D (test-runner-fail-count (test-runner-current)) 0))))) + + (gexp->derivation "php-fpm-test" test)) + +(define %test-php-fpm + (system-test + (name "php-fpm") + (description "Test PHP-FPM through nginx.") + (value (run-php-fpm-test)))) --=20 2.14.2 --MP_/TvWRodwxy3TnNo5jMlnjt6B-- --Sig_/KViE2HtsC71FhzZ_pYG4OFd Content-Type: application/pgp-signature Content-Description: OpenPGP digital signature -----BEGIN PGP SIGNATURE----- iQKTBAEBCgB9FiEEPonu50WOcg2XVOCyXiijOwuE9XcFAln7bzRfFIAAAAAALgAo aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldDNF ODlFRUU3NDU4RTcyMEQ5NzU0RTBCMjVFMjhBMzNCMEI4NEY1NzcACgkQXiijOwuE 9Xf9Sw//f2AhkGfknIBvLHrgPalnihCsDJ0okv+EteAgOkYGz+RnNy55ABub2LR7 CqH0kUmDSduIngmkagcYsmF1GX9hfQ5itJzMfFzbDfjRYI809ktalbXL06/4ck3J WJl2I6lQ1nlYdkG524t6WTRyHlk0sU4Ko4IVepCjTZGjKKPhX90g7pjX28mR+Cse 7nI0P9BeJN49+GxyA/OZOKKPlEMuC3k6w9hXvjUHxZ3l7oirRLFTDDboAAOzOvP8 SayUz9nQ5Bme95et3JYnbiBvTl46WrV8gWALqBrOZfZUQp64v9ngb3NBPp7He+sI NctzEltdQF/kISRBVJjdE3zbOMBEfMMXQofvJZD7+wLxz+Kp++DKGN0/gtweY7sn iSfkU3nPwI2NlhPJn7Fa3ey7li0K8feC5A5XqtL1M0h8YixbCjBCPE41TgfO2RiD S6l+Kvpeq26Ag2y1L9i+nvWNaONO896hYhdqRHBNneDhENbXpXanIQUk7gSaylei cqd2giK5kPmvjkYUbZJuaHGAgObzFh1eUNYMN9ta9IgOF+7F8PbU1xxAu610wY9d MOOP/GJTGR2T+XT8m/kG1HAZBOluftU+w3cufejDU2UKLU7eyMNyteYXP4tfsr7S i9OCkwblg8hsPMY8HvxcLLeHHkjGuHHI1DCvew1AU4SS4naXVqs= =a7i4 -----END PGP SIGNATURE----- --Sig_/KViE2HtsC71FhzZ_pYG4OFd-- From debbugs-submit-bounces@debbugs.gnu.org Thu Nov 23 15:12:03 2017 Received: (at 28769) by debbugs.gnu.org; 23 Nov 2017 20:12:03 +0000 Received: from localhost ([127.0.0.1]:54182 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eHxqn-000824-HR for submit@debbugs.gnu.org; Thu, 23 Nov 2017 15:12:03 -0500 Received: from cock.li ([185.100.85.212]:59820) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eHxqk-00081p-FD for 28769@debbugs.gnu.org; Thu, 23 Nov 2017 15:11:56 -0500 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on cock.li X-Spam-Status: No, score=0.8 required=5.0 tests=BAYES_50 shortcircuit=_SCTYPE_ autolearn=disabled version=3.4.1 From: nee DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cock.li; s=mail; t=1511467907; bh=1peFEp3ps7eEAMl0qsq2HWDJYH9gUpxk9rowCHMhfC4=; h=From:Subject:To:Cc:References:Date:In-Reply-To:From; b=wPOjoGlndbRb5V8i35uvshCWJpBChViqR8TvbFu1SrU1BcYkqqvPl+DsecCsgSGB3 U4h6MSNKQP6TRxkcOPMSNbXTmdBWY4u/lXjNprl6G9mob3Cz6DqQcB8WepLlbpOtKB Yr+fPzkTokkvaoh5kfyNWFqy1hnL34SZYHV0O/TlmdngWHz26V2QXAfHVwOTXJ8BXG eH1/ESxGdNXjExypYAPl5P+ETE65T05mp6rLugS7UPjODG6C/f4OJ0nMlAErHbvNYE BsYEsASzgCzbCWzQ5SqBvee/rL08ZR4voeUIMubbwbA7v4yDH2mpPAVMtLYsVhxpND YZnkg6M2+qMKA== Subject: Re: [bug#28769] [PATCH] gnu: services: Add php-fpm. To: Christopher Baines References: <9fe1701f-d78f-ba3a-37eb-64417337a55b@cock.li> <20171013223729.2605f33c@cbaines.net> <7462cec0-7d33-f2a3-1bd7-92454d690b0b@cock.li> <20171102191708.0cf85810@cbaines.net> Message-ID: <145a6af6-bf20-c6e3-f314-009a17239f89@cock.li> Date: Thu, 23 Nov 2017 21:11:48 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0 MIME-Version: 1.0 In-Reply-To: <20171102191708.0cf85810@cbaines.net> Content-Type: multipart/mixed; boundary="------------64BC90A7CEF2FF28A82C607A" Content-Language: en-GB X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 28769 Cc: 28769@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) This is a multi-part message in MIME format. --------------64BC90A7CEF2FF28A82C607A Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Hello sorry about not replying for such a long time, and thank you for reviewing my patches again. Am 02.11.2017 um 20:17 schrieb Christopher Baines: > > I've now attached a system test for php-fpm, that sets it up with > nginx, creates a basic php file, and checks that it can be requested. That's great thanks for saving me a bunch of work with this. ;-) > > This seems to work, which I was a little surprised at, as I was > suspecting problems with the socket permissions. > > I had a look, and while the nginx workers in the test system are not > root, the nginx master process is, so maybe that allows it to work... I don't think that's the reason, because I remember it not working at first when I didn't have the permissions set. >> I renamed the default workers-log-file to php7-fpm.www.log as it is >> usually called. The php-fpm log-file is now called php7-fpm.log. > > What I think I meant to say here was, I'm not sure the php _version_ is > adding much to the log file name (rather than "I'm not sure the php is > adding"). > > The php package version is used in a few places, and while I can > imagine this being consistent with other distributions, it does add a > bit of complexity to the default values in the service, and I'm not > sure what benefit it brings? > If users want to run multiple php versions, they only have to change the version in the php-package and pass that package along all the services. My perception of the php landscape was that the major releases aren't 100% reliably backwards compatible and some applications depend on older stable releases, so that it is not too uncommon to run multiple php versions the same system. Here is a quote from: https://wordpress.org/about/requirements/ """ Why do we support older versions? We strongly recommend the latest versions of PHP and MySQL, but we understand that this isn’t right for everyone, and that sometimes hosts can be slow or hesitant to upgrade their customers since upgrades to PHP and MySQL have historically broken applications. """ An alternative could be to include the php-package hash in the socket name, but I'm not sure if that would work with nginx and it's currently missing reload when a system-reconfigure is done. Or services could be generally more isolated somehow. WDYT? >>>> + (file php-fpm-configuration-file ;#f | file-like >>>> + (default #f))) > > ... > >>>> + (service-extension account-service-type >>>> + php-fpm-accounts))) >>>> + (default-value (php-fpm-configuration)))) >>> >>> Filling in the description (a relatively new field on the service type) >>> would be a great addition here. >>> >> Ah, yes I'm mostly using the web documentation and other services from >> web.scm as reference. Thanks for the update. >> What would be a good value for this field? I just used "The php-fpm >> service-type." for now. > > That is ok, but it could probably be more useful. I think ideally it > would describe more about what the service offers. > > Users might encounter this when searching for services for example: > > → guix system search php > name: php-fpm > location: gnu/services/web.scm:607:2 > extends: shepherd-root activate account > description: The php-fpm service-type. > relevance: 5 I ran `guix sysytem search *` and it seems most descriptions start with 'Run' or 'Provide' I changed it to: "Run `php-fpm' to provide a fastcgi socket for calling php through a webserver." > I've attached a patch containing a couple of copy+paste fixes, and a > system test. > > It would be good to get your opinion on the system test, does it test > the right things? > The tests look good to me. I added another test that adds two numbers and checks for the result in the response to see if php actually did something with the file. > If you like the look of it, I'd suggest including those changes in the > commit that adds the service, and then sending the updated patches. > I've included a changelog in the commit message. > Here are the updated patches. Thank you for your tests! --------------64BC90A7CEF2FF28A82C607A 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 5347b2880b92e055cb8df1ea2c68ece74f506180 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 procedure. --- guix/utils.scm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/guix/utils.scm b/guix/utils.scm index c0ffed172..bfa5e3a69 100644 --- a/guix/utils.scm +++ b/guix/utils.scm @@ -80,6 +80,7 @@ version>=3D? version-prefix version-major+minor + version-major guile-version>? string-replace-substring arguments-from-environment-variable @@ -492,6 +493,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 --------------64BC90A7CEF2FF28A82C607A 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 a9061ce9dafc1454e5b964e6c9e16c9269356ca5 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. * gnu/tests/web.scm: Add php-fpm system test. --- doc/guix.texi | 137 +++++++++++++++++++++++++++- gnu/services/web.scm | 248 +++++++++++++++++++++++++++++++++++++++++++++= +++++- gnu/tests/web.scm | 123 ++++++++++++++++++++++++- 3 files changed, 504 insertions(+), 4 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index d4a2a696a..9058c9a23 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -40,7 +40,8 @@ Copyright @copyright{} 2017 Christopher Allan Webber@* Copyright @copyright{} 2017 Marius Bakke@* Copyright @copyright{} 2017 Hartmut Goebel@* Copyright @copyright{} 2017 Maxim Cournoyer@* -Copyright @copyright{} 2017 Tobias Geerinckx-Rice +Copyright @copyright{} 2017 Tobias Geerinckx-Rice@* +Copyright @copyright{} 2017 nee =20 Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or @@ -14942,6 +14943,140 @@ capability also has to be configured on the fro= nt-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. + +These features include: +@itemize @bullet +@item Adaptive process spawning +@item Basic statistics (ala Apache's mod_status) +@item Advanced process management with graceful stop/start +@item Ability to start workers with different uid/gid/chroot/environment= +and different php.ini (replaces safe_mode) +@item Stdout & stderr logging +@item Emergency restart in case of accidental opcode cache destruction +@item Accelerated upload support +@item Support for a "slowlog" +@item Enhancements to FastCGI, such as fastcgi_finish_request() - +a special function to finish request & flush all data while continuing t= o do +something time-consuming (video converting, stats processing, etc.) +@end itemize +... and much more. + +@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{php-fpm}) +User who can speak to the php-fpm socket. +@item @code {socket-group} (default: @code{php-fpm}) +Group that can speak to the php-fpm socket. +@item @code {pid-file} (default: @code{(string-append "/var/log/php" (ve= rsion-major (package-version php)) "-fpm.pid")}) +The process id of the php-fpm process is written to this file +once the service has started. +@item @code {log-file} (default: @code{(string-append "/var/log/php" (ve= rsion-major (package-version php)) "-fpm.log")}) +Log for the php-fpm master process. +@item @code {process-manager} (default: @code{(php-fpm-dynamic-process-m= anager-configuration)}) +Detailed settings for the php-fpm process manager. +Must be either: +@table @asis +@item @code{} +@item @code{} +@item @code{} +@end table +@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.www.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-dynamic-process-manager-configuration +Data Type for the @code{dynamic} php-fpm process manager. +With the @code{dynamic} process manager spare worker processes are kept = around +based on it's configured limits. +@table @asis +@item @code {max-children} (default: @code{5}) +Maximum of worker processes. +@item @code {start-servers} (default: @code{2}) +How many worker processes should be started on start-up. +@item @code {min-spare-servers} (default: @code{1}) +How many spare worker processes should be kept around at minimum. +@item @code {max-spare-servers} (default: @code{3}) +How many spare worker processes should be kept around at maximum. +@end table +@end deftp + +@deftp {Data type} php-fpm-static-process-manager-configuration +Data Type for the @code{static} php-fpm process manager. +With the @code{static} process manager an unchanging number +of worker processes is created. +@table @asis +@item @code {max-children} (default: @code{5}) +Maximum of worker processes. +@end table +@end deftp + +@deftp {Data type} php-fpm-on-demand-process-manager-configuration +Data Type for the @code{on-demand} php-fpm process manager. +With the @code{on-demand} process manager worker processes are only crea= ted +as requests arrive. +@table @asis +@item @code {max-children} (default: @code{5}) +Maximum of worker processes. +@item @code {process-idle-timeout} (default: @code{10}) +The time in seconds after which a process with no requests is killed. +@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) + (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..3b3be215a 100644 --- a/gnu/services/web.scm +++ b/gnu/services/web.scm @@ -4,6 +4,7 @@ ;;; Copyright =C2=A9 2016 ng0 ;;; Copyright =C2=A9 2016, 2017 Julien Lepiller ;;; Copyright =C2=A9 2017 Christopher Baines +;;; Copyright =C2=A9 2017 nee ;;; ;;; This file is part of GNU Guix. ;;; @@ -26,8 +27,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 +80,49 @@ =20 fcgiwrap-configuration fcgiwrap-configuration? - fcgiwrap-service-type)) + 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-workers-log-file + php-fpm-configuration-file + =20 + + 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-serv= ers + php-fpm-dynamic-process-manager-configuration-max-spare-serv= ers + =20 + + 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 + =20 + + 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)) =20 ;;; Commentary: ;;; @@ -256,10 +302,12 @@ of index files." "events {}\n"))) =20 (define %nginx-accounts - (list (user-group (name "nginx") (system? #t)) + (list (user-group (name "php-fpm") (system? #t)) + (user-group (name "nginx") (system? #t)) (user-account (name "nginx") (group "nginx") + (supplementary-groups '("php-fpm")) (system? #t) (comment "nginx server user") (home-directory "/var/empty") @@ -385,3 +433,199 @@ 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-vers= ion 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 "php-fpm")) + (pid-file php-fpm-configuration-pid-file + (default (string-append "/var/run/php" + (version-major (package-vers= ion php)) + "-fpm.pid"))) + (log-file php-fpm-configuration-log-file + (default (string-append "/var/log/php" + (version-major (package-vers= ion php)) + "-fpm.log"))) + (process-manager php-fpm-configuration-process-manager + (default (php-fpm-dynamic-process-manager-configurat= ion))) + (display-errors php-fpm-configuration-display-errors + (default #f)) + (workers-log-file php-fpm-configuration-workers-log-file + (default (string-append "/var/log/php" + (version-major (package-vers= ion php)) + "-fpm.www.log"))) + (file php-fpm-configuration-file ;#f | file-like + (default #f))) + +(define-record-type* + php-fpm-dynamic-process-manager-configuration + make-php-fpm-dynamic-process-manager-configuration + php-fpm-dynamic-process-manager-configuration? + (max-children php-fpm-dynamic-process-manager-configuration-ma= x-children + (default 5)) + (start-servers php-fpm-dynamic-process-manager-configuration-st= art-servers + (default 2)) + (min-spare-servers php-fpm-dynamic-process-manager-configuration-mi= n-spare-servers + (default 1)) + (max-spare-servers php-fpm-dynamic-process-manager-configuration-ma= x-spare-servers + (default 3))) + +(define-record-type* + php-fpm-static-process-manager-configuration + make-php-fpm-static-process-manager-configuration + php-fpm-static-process-manager-configuration? + (max-children php-fpm-static-process-manager-configuration-max= -children + (default 5))) + +(define-record-type* + php-fpm-on-demand-process-manager-configuration + make-php-fpm-on-demand-process-manager-configuration + php-fpm-on-demand-process-manager-configuration? + (max-children php-fpm-on-demand-process-manager-configuration-= max-children + (default 5)) + (process-idle-timeout php-fpm-on-demand-process-manager-configuration-= process-idle-timeout + (default 10))) + +(define php-fpm-accounts + (match-lambda + (($ php socket user group socket-user socket= -group _ _ _ _ _ _) + (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"))))))) + +(define (default-php-fpm-config socket user group socket-user socket-gro= up + pid-file log-file pm display-errors workers-log-file) + (apply mixed-text-file "php-fpm.conf" + (flatten + "[global]\n" + "pid =3D" pid-file "\n" + "error_log =3D" log-file "\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" + + (match pm + (($ + pm.max-children + pm.start-servers + pm.min-spare-servers + pm.max-spare-servers) + (list + "pm =3D dynamic\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-se= rvers) "\n" + "pm.max_spare_servers =3D" (number->string pm.max-spare-se= rvers) "\n")) + =20 + (($ + pm.max-children) + (list + "pm =3D static\n" + "pm.max_children =3D" (number->string pm.max-children) "\n= ")) + =20 + (($ + pm.max-children + pm.process-idle-timeout) + (list + "pm =3D ondemand\n" + "pm.max_children =3D" (number->string pm.max-children) "\n= " + "pm.process_idle_timeout =3D" (number->string pm.process-i= dle-timeout) "s\n"))) + + + "php_flag[display_errors] =3D " (if display-errors "on" "off")= "\n" + + (if workers-log-file + (list "catch_workers_output =3D yes\n" + "php_admin_value[error_log] =3D" workers-log-file "\= 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 + pid-file log-file pm display-errors work= ers-log-file 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") + "--fpm-config" + #$(or file + (default-php-fpm-config socket user group + socket-user socket-group pid-file log-fi= le + pm display-errors workers-log-file))) + #:pid-file #$pid-file)) + (stop #~(make-kill-destructor))))))) + +(define php-fpm-activation + (match-lambda + (($ _ _ user _ _ _ _ log-file _ _ workers-lo= g-file _) + #~(begin + (use-modules (guix build utils)) + (let* ((user (getpwnam #$user)) + (touch (lambda (file-name) + (call-with-output-file file-name (const #t)))) + (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 #$log-file) + (init-log-file #$workers-log-file)))))) + + +(define php-fpm-service-type + (service-type (name 'php-fpm) + (description "Run `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)))) + +(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= ;"))))) diff --git a/gnu/tests/web.scm b/gnu/tests/web.scm index 3fa272c67..68233af9f 100644 --- a/gnu/tests/web.scm +++ b/gnu/tests/web.scm @@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright =C2=A9 2017 Ludovic Court=C3=A8s +;;; Copyright =C2=A9 2017 Christopher Baines ;;; ;;; This file is part of GNU Guix. ;;; @@ -27,7 +28,8 @@ #:use-module (gnu services networking) #:use-module (guix gexp) #:use-module (guix store) - #:export (%test-nginx)) + #:export (%test-nginx + %test-php-fpm)) =20 (define %index.html-contents ;; Contents of the /index.html file served by nginx. @@ -132,3 +134,122 @@ HTTP-PORT." (name "nginx") (description "Connect to a running NGINX server.") (value (run-nginx-test)))) + +=0C +;;; +;;; PHP-FPM +;;; + +(define %make-php-fpm-http-root + ;; Create our server root in /srv. + #~(begin + (mkdir "/srv") + (call-with-output-file "/srv/index.php" + (lambda (port) + (display "\n" port))))) + +(define %php-fpm-nginx-server-blocks + (list (nginx-server-configuration + (root "/srv") + (locations + (list (nginx-php-location))) + (http-port 8042) + (https-port #f) + (ssl-certificate #f) + (ssl-certificate-key #f)))) + +(define %php-fpm-os + ;; Operating system under test. + (simple-operating-system + (dhcp-client-service) + (service php-fpm-service-type) + (service nginx-service-type + (nginx-configuration + (server-blocks %php-fpm-nginx-server-blocks))) + (simple-service 'make-http-root activation-service-type + %make-php-fpm-http-root))) + +(define* (run-php-fpm-test #:optional (http-port 8042)) + "Run tests in %PHP-FPM-OS, which has nginx running and listening on +HTTP-PORT, along with php-fpm." + (define os + (marionette-operating-system + %php-fpm-os + #:imported-modules '((gnu services herd) + (guix combinators)))) + + (define vm + (virtual-machine + (operating-system os) + (port-forwardings `((8080 . ,http-port))))) + + (define test + (with-imported-modules '((gnu build marionette) + (guix build utils)) + #~(begin + (use-modules (srfi srfi-11) (srfi srfi-64) + (gnu build marionette) + (web uri) + (web client) + (web response)) + + (define marionette + (make-marionette (list #$vm))) + + (mkdir #$output) + (chdir #$output) + + (test-begin "php-fpm") + + (test-assert "php-fpm running" + (marionette-eval + '(begin + (use-modules (gnu services herd)) + (match (start-service 'php-fpm) + (#f #f) + (('service response-parts ...) + (match (assq-ref response-parts 'running) + ((pid) (number? pid)))))) + marionette)) + + (test-eq "nginx running" + 'running! + (marionette-eval + '(begin + (use-modules (gnu services herd)) + (start-service 'nginx) + 'running!) + marionette)) + + (test-equal "http-get" + 200 + (let-values (((response text) + (http-get "http://localhost:8080/index.php" + #:decode-body? #t))) + (response-code response))) + + (test-equal "php computed result is sent" + "Computed by php:5" + (let-values (((response text) + (http-get "http://localhost:8080/index.php" + #:decode-body? #t))) + (begin + (use-modules (ice-9 regex)) + (let ((matches (string-match "Computed by php:5" text)))= + (and matches + (match:substring matches 0)))))) + + (test-end) + + (exit (=3D (test-runner-fail-count (test-runner-current)) 0)))= )) + + (gexp->derivation "php-fpm-test" test)) + +(define %test-php-fpm + (system-test + (name "php-fpm") + (description "Test PHP-FPM through nginx.") + (value (run-php-fpm-test)))) --=20 2.14.1 --------------64BC90A7CEF2FF28A82C607A-- From debbugs-submit-bounces@debbugs.gnu.org Sat Dec 09 17:08:50 2017 Received: (at 28769) by debbugs.gnu.org; 9 Dec 2017 22:08:50 +0000 Received: from localhost ([127.0.0.1]:54261 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eNnIg-0005Er-6f for submit@debbugs.gnu.org; Sat, 09 Dec 2017 17:08:50 -0500 Received: from li622-129.members.linode.com ([212.71.249.129]:56756 helo=mira.cbaines.net) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eNnId-0005Ei-7x for 28769@debbugs.gnu.org; Sat, 09 Dec 2017 17:08:48 -0500 Received: by mira.cbaines.net (Postfix, from userid 113) id 594A713D22C; Sat, 9 Dec 2017 22:08:46 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from localhost (cpc102582-walt20-2-0-cust14.13-2.cable.virginm.net [86.27.34.15]) by mira.cbaines.net (Postfix) with ESMTPSA id 916BE13D228; Sat, 9 Dec 2017 22:08:45 +0000 (GMT) Received: from giedi (localhost [127.0.0.1]) by localhost (OpenSMTPD) with ESMTP id 290b2116; Sat, 9 Dec 2017 22:08:45 +0000 (UTC) References: <9fe1701f-d78f-ba3a-37eb-64417337a55b@cock.li> <20171013223729.2605f33c@cbaines.net> <7462cec0-7d33-f2a3-1bd7-92454d690b0b@cock.li> <20171102191708.0cf85810@cbaines.net> <145a6af6-bf20-c6e3-f314-009a17239f89@cock.li> User-agent: mu4e 0.9.18; emacs 25.3.1 From: Christopher Baines To: nee Subject: Re: [bug#28769] [PATCH] gnu: services: Add php-fpm. In-reply-to: <145a6af6-bf20-c6e3-f314-009a17239f89@cock.li> Date: Sat, 09 Dec 2017 22:08:40 +0000 Message-ID: <874loz7dw7.fsf@cbaines.net> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="==-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 28769 Cc: 28769@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) --==-=-= Content-Type: multipart/mixed; boundary="=-=-=" --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable nee writes: > Hello sorry about not replying for such a long time, and thank you for > reviewing my patches again. > > Am 02.11.2017 um 20:17 schrieb Christopher Baines: >> >> I've now attached a system test for php-fpm, that sets it up with >> nginx, creates a basic php file, and checks that it can be requested. > > That's great thanks for saving me a bunch of work with this. ;-) > >> >> This seems to work, which I was a little surprised at, as I was >> suspecting problems with the socket permissions. >> >> I had a look, and while the nginx workers in the test system are not >> root, the nginx master process is, so maybe that allows it to work... > I don't think that's the reason, because I remember it not working at > first when I didn't have the permissions set. Yep, my mistake. I didn't spot the changes to the nginx service. >>> I renamed the default workers-log-file to php7-fpm.www.log as it is >>> usually called. The php-fpm log-file is now called php7-fpm.log. >> >> What I think I meant to say here was, I'm not sure the php _version_ is >> adding much to the log file name (rather than "I'm not sure the php is >> adding"). >> >> The php package version is used in a few places, and while I can >> imagine this being consistent with other distributions, it does add a >> bit of complexity to the default values in the service, and I'm not >> sure what benefit it brings? >> > If users want to run multiple php versions, they only have to change the > version in the php-package and pass that package along all the services. > > My perception of the php landscape was that the major releases aren't > 100% reliably backwards compatible and some applications depend on older > stable releases, so that it is not too uncommon to run multiple php > versions the same system. > > Here is a quote from: https://wordpress.org/about/requirements/ > > """ > Why do we support older versions? > > We strongly recommend the latest versions of PHP and MySQL, but we > understand that this isn=E2=80=99t right for everyone, and that sometimes= hosts > can be slow or hesitant to upgrade their customers since upgrades to PHP > and MySQL have historically broken applications. > """ > > An alternative could be to include the php-package hash in the socket > name, but I'm not sure if that would work with nginx and it's currently > missing reload when a system-reconfigure is done. Or services could be > generally more isolated somehow. > > WDYT? That sounds good to me. I don't know too much about this area though. >>>>> + (file php-fpm-configuration-file ;#f | file-like >>>>> + (default #f))) >> >> ... >> >>>>> + (service-extension account-service-type >>>>> + php-fpm-accounts))) >>>>> + (default-value (php-fpm-configuration)))) >>>> >>>> Filling in the description (a relatively new field on the service type) >>>> would be a great addition here. >>>> >>> Ah, yes I'm mostly using the web documentation and other services from >>> web.scm as reference. Thanks for the update. >>> What would be a good value for this field? I just used "The php-fpm >>> service-type." for now. >> >> That is ok, but it could probably be more useful. I think ideally it >> would describe more about what the service offers. >> >> Users might encounter this when searching for services for example: >> >> =E2=86=92 guix system search php >> name: php-fpm >> location: gnu/services/web.scm:607:2 >> extends: shepherd-root activate account >> description: The php-fpm service-type. >> relevance: 5 > > I ran `guix sysytem search *` and it seems most descriptions start with > 'Run' or 'Provide' I changed it to: > "Run `php-fpm' to provide a fastcgi socket for calling php through a > webserver." > > >> I've attached a patch containing a couple of copy+paste fixes, and a >> system test. >> >> It would be good to get your opinion on the system test, does it test >> the right things? >> > The tests look good to me. > I added another test that adds two numbers and checks for the result in > the response to see if php actually did something with the file. > >> If you like the look of it, I'd suggest including those changes in the >> commit that adds the service, and then sending the updated patches. >> I've included a changelog in the commit message. >> > Here are the updated patches. Thank you for your tests! Thanks for picking this up again. Unfortunately it's also take me a long time to get back around to looking at this. I've attached some changes that I thought would be good when I was looking through this. To give a rough summary: - Minor improvements to the docs, either content, markup or formatting. - Removing trailing whitespace. - Removing the changes to the nginx-service, in favour of changing the default socket group. - Change some indentation to avoid long lines. By changing the default socket group, the system test passes, even without the changes to the nginx service. I think this is a bit better, and while it's definately not perfect, I think it would be ok to merge with this change. To also try and move the first patch forward, I've submitted that within #29629, with an additional patch to get other services using version-major. It would be good to get your thoughts on the changes in the attached patch, and then if you could send an updated set of patches, that would be great. As far as I remember, the changes to the nginx service were the only thing I felt needed addressing before merging this. Thanks, Chris --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=patch Content-Transfer-Encoding: quoted-printable Content-Description: Some changes to the php-fpm service and docs diff --git a/doc/guix.texi b/doc/guix.texi index f2ef941b4..dcab3bd76 100644 =2D-- a/doc/guix.texi +++ b/doc/guix.texi @@ -15173,7 +15173,7 @@ with some additional features useful for sites of a= ny size. These features include: @itemize @bullet @item Adaptive process spawning =2D@item Basic statistics (ala Apache's mod_status) +@item Basic statistics (similar to Apache's mod_status) @item Advanced process management with graceful stop/start @item Ability to start workers with different uid/gid/chroot/environment and different php.ini (replaces safe_mode) @@ -15194,7 +15194,9 @@ A Service type for @code{php-fpm}. @deftp {Data Type} php-fpm-configuration Data Type for php-fpm service configuration. @table @asis =2D@item @code {socket} (default: @code{(string-append "/var/run/php" (vers= ion-major (package-version php)) "-fpm.sock")}) +@item @code{php} (default: @code{php}) +The php package to use. +@item @code{socket} (default: @code{(string-append "/var/run/php" (version= -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"} @@ -15205,20 +15207,20 @@ Listen on a TCP socket to all addresses on a spec= ific port. Listen on a unix socket. @end table =20 =2D@item @code {user} (default: @code{php-fpm}) +@item @code{user} (default: @code{php-fpm}) User who will own the php worker processes. =2D@item @code {group} (default: @code{php-fpm}) +@item @code{group} (default: @code{php-fpm}) Group of the worker processes. =2D@item @code {socket-user} (default: @code{php-fpm}) +@item @code{socket-user} (default: @code{php-fpm}) User who can speak to the php-fpm socket. =2D@item @code {socket-group} (default: @code{php-fpm}) +@item @code{socket-group} (default: @code{php-fpm}) Group that can speak to the php-fpm socket. =2D@item @code {pid-file} (default: @code{(string-append "/var/log/php" (ve= rsion-major (package-version php)) "-fpm.pid")}) +@item @code{pid-file} (default: @code{(string-append "/var/run/php" (versi= on-major (package-version php)) "-fpm.pid")}) The process id of the php-fpm process is written to this file once the service has started. =2D@item @code {log-file} (default: @code{(string-append "/var/log/php" (ve= rsion-major (package-version php)) "-fpm.log")}) +@item @code{log-file} (default: @code{(string-append "/var/log/php" (versi= on-major (package-version php)) "-fpm.log")}) Log for the php-fpm master process. =2D@item @code {process-manager} (default: @code{(php-fpm-dynamic-process-m= anager-configuration)}) +@item @code{process-manager} (default: @code{(php-fpm-dynamic-process-mana= ger-configuration)}) Detailed settings for the php-fpm process manager. Must be either: @table @asis @@ -15226,62 +15228,66 @@ Must be either: @item @code{} @item @code{} @end table =2D@item @code {display-errors} (default @code{#f}) +@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 s= ites, as error messages can reveal passwords and personal data. =2D@item @code {workers-logfile} (default @code{(string-append "/var/log/ph= p" (version-major (package-version php)) "-fpm.www.log")}) +@item @code{workers-logfile} (default @code{(string-append "/var/log/php" = (version-major (package-version php)) "-fpm.www.log")}) This file will log the @code{stderr} outputs of php worker processes. Can be set to @code{#f} to disable logging. =2D@item @code {file} (default @code{#f}) +@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 fo= r it. @end table @end deftp =20 @deftp {Data type} php-fpm-dynamic-process-manager-configuration =2DData Type for the @code{dynamic} php-fpm process manager. =2DWith the @code{dynamic} process manager spare worker processes are kept = around +Data Type for the @code{dynamic} php-fpm process manager. With the +@code{dynamic} process manager, spare worker processes are kept around based on it's configured limits. @table @asis =2D@item @code {max-children} (default: @code{5}) +@item @code{max-children} (default: @code{5}) Maximum of worker processes. =2D@item @code {start-servers} (default: @code{2}) +@item @code{start-servers} (default: @code{2}) How many worker processes should be started on start-up. =2D@item @code {min-spare-servers} (default: @code{1}) +@item @code{min-spare-servers} (default: @code{1}) How many spare worker processes should be kept around at minimum. =2D@item @code {max-spare-servers} (default: @code{3}) +@item @code{max-spare-servers} (default: @code{3}) How many spare worker processes should be kept around at maximum. @end table @end deftp =20 @deftp {Data type} php-fpm-static-process-manager-configuration =2DData Type for the @code{static} php-fpm process manager. =2DWith the @code{static} process manager an unchanging number =2Dof worker processes is created. +Data Type for the @code{static} php-fpm process manager. With the +@code{static} process manager, an unchanging number of worker processes +are created. @table @asis =2D@item @code {max-children} (default: @code{5}) +@item @code{max-children} (default: @code{5}) Maximum of worker processes. @end table @end deftp =20 @deftp {Data type} php-fpm-on-demand-process-manager-configuration =2DData Type for the @code{on-demand} php-fpm process manager. =2DWith the @code{on-demand} process manager worker processes are only crea= ted =2Das requests arrive. +Data Type for the @code{on-demand} php-fpm process manager. With the +@code{on-demand} process manager, worker processes are only created as +requests arrive. @table @asis =2D@item @code {max-children} (default: @code{5}) +@item @code{max-children} (default: @code{5}) Maximum of worker processes. =2D@item @code {process-idle-timeout} (default: @code{10}) +@item @code{process-idle-timeout} (default: @code{10}) The time in seconds after which a process with no requests is killed. @end table @end deftp =20 =20 =2D@defvr {Scheme Variable} nginx-php-fpm-location +@deffn {Scheme Procedure} nginx-php-fpm-location @ + [#:nginx-package nginx] @ + [socket (string-append "/var/run/php" @ + (version-major (package-version php)) @ + "-fpm.sock")] A helper function to quickly add php to an @code{nginx-server-configuratio= n}. =2D@end defvr +@end deffn =20 A simple services setup for nginx with php can look like this: @example diff --git a/gnu/services/web.scm b/gnu/services/web.scm index 3b3be215a..00599df6d 100644 =2D-- a/gnu/services/web.scm +++ b/gnu/services/web.scm @@ -98,7 +98,7 @@ php-fpm-configuration-display-errors php-fpm-configuration-workers-log-file php-fpm-configuration-file =2D=20=20=20=20=20=20=20=20=20=20=20=20 + php-fpm-dynamic-process-manager-configuration make-php-fpm-dynamic-process-manager-configuration @@ -107,13 +107,13 @@ 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 =2D=20=20=20=20=20=20=20=20=20=20=20=20 + 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 =2D=20=20=20=20=20=20=20=20=20=20=20=20 + php-fpm-on-demand-process-manager-configuration make-php-fpm-on-demand-process-manager-configuration @@ -302,12 +302,10 @@ of index files." "events {}\n"))) =20 (define %nginx-accounts =2D (list (user-group (name "php-fpm") (system? #t)) =2D (user-group (name "nginx") (system? #t)) + (list (user-group (name "nginx") (system? #t)) (user-account (name "nginx") (group "nginx") =2D (supplementary-groups '("php-fpm")) (system? #t) (comment "nginx server user") (home-directory "/var/empty") @@ -450,7 +448,7 @@ of index files." (socket-user php-fpm-configuration-socket-user (default "php-fpm")) (socket-group php-fpm-configuration-socket-group =2D (default "php-fpm")) + (default "nginx")) (pid-file php-fpm-configuration-pid-file (default (string-append "/var/run/php" (version-major (package-versio= n php)) @@ -542,13 +540,13 @@ of index files." "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")) =2D=20=20=20=20=20=20=20=20=20=20=20=20 + (($ pm.max-children) (list "pm =3D static\n" "pm.max_children =3D" (number->string pm.max-children) "\n")) =2D=20=20=20=20=20=20=20=20=20=20=20=20 + (($ pm.max-children pm.process-idle-timeout) @@ -604,16 +602,19 @@ of index files." =20 =20 (define php-fpm-service-type =2D (service-type (name 'php-fpm) =2D (description "Run `php-fpm' to provide a fastcgi socket = for calling php through a webserver.") =2D (extensions =2D (list (service-extension shepherd-root-service-type =2D php-fpm-shepherd-service) =2D (service-extension activation-service-type =2D php-fpm-activation) =2D (service-extension account-service-type =2D php-fpm-accounts))) =2D (default-value (php-fpm-configuration)))) + (service-type + (name 'php-fpm) + (description + "Run @command{php-fpm} to provide a fastcgi socket for calling php thr= ough +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)))) =20 (define* (nginx-php-location #:key --=-=-=-- --==-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQKTBAEBCgB9FiEEPonu50WOcg2XVOCyXiijOwuE9XcFAlosXuhfFIAAAAAALgAo aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldDNF ODlFRUU3NDU4RTcyMEQ5NzU0RTBCMjVFMjhBMzNCMEI4NEY1NzcACgkQXiijOwuE 9XffGhAArWHa8fytG1yUNEJFunDm3aDGU5iWW59aYidpCIYHTe1EdUDZtq5Dpj9r pJz9J5ecKJdljpCnHHxPly1UzqK4raxPXT+NQxUlm7Iy1AmVizN9ISjp5CBTxY+c 69+tuciN8FKhV31DzZev/028okF3BIJa4rQCLBoZd5TCnmC2CAebhKKY1canr0Mg pGyX/LGfrChJy5Zwe9MWN3p2wLM7T8QAfPd6QWVBUhBrLop3JCh60pRet5LWU9Fa xUkBurR2yd5q6ibfNAGl6MA25gAQ4xiUw0sC5XvnJcqklJSKET7Yxsaxqupsr3/w mhpjMIEt1IyXLtQs6BCv5VmOohfCBMTgduwj7WvQNxNgTfQxv27K3sMOVUtl6DRB ST621jmukpCbky3K4/6RThgUke1nGbnMeBjWX7oA+dvi8XZ7OBTWvGfRCtAzCz54 m0Y9vwzeh1XYAxg7lYxKRk7xML7DDlvBf3OO71Rks9XuzxT751F/6OryDbi7julk BoQGzDtUJDlnLhuHgNgnP6U05YB/6GTOvwo8YeNK/b9qhLzp30LXiG9tm/Y3nwae hkci6QjtFYdUpyQUzq8xRXmiEDA7A6trOmS/PNN19n+N3EVcP1Dll+qsNS/VeNZ4 OePex3wmFm9ha7+YlgtvwKcq6057gs9NBOSLbZj/a0MV+duJFCE= =ZJkC -----END PGP SIGNATURE----- --==-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Mon Dec 11 13:19:23 2017 Received: (at 28769) by debbugs.gnu.org; 11 Dec 2017 18:19:23 +0000 Received: from localhost ([127.0.0.1]:57194 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eOSfj-0001fw-5h for submit@debbugs.gnu.org; Mon, 11 Dec 2017 13:19:23 -0500 Received: from cock.li ([185.100.85.212]:38189) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eOSfg-0001fb-He for 28769@debbugs.gnu.org; Mon, 11 Dec 2017 13:19:21 -0500 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on cock.li X-Spam-Status: No, score=-0.0 required=5.0 tests=BAYES_40 shortcircuit=_SCTYPE_ autolearn=disabled version=3.4.1 Subject: Re: [bug#28769] [PATCH] gnu: services: Add php-fpm. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cock.li; s=mail; t=1513016353; bh=mam87ujT/I0iAG22GUSm3HLx/WTCInnCqRT2dCa+2xs=; h=Subject:To:Cc:References:From:Date:In-Reply-To:From; b=iyLcwz88WEvvEjSgJop0G192QXWovkbTUa8pwrhNnKhSNVJjfpu6aKQmYQh4fRhTQ O4h19oBsn+I1iUKzV1U77j3AvTumQjB3yu6Gf6un/8eUeUnnxmpRgPuSpFwIlO8H6P o8W4HjCoiSXrwoIjqOgOa2zxbooAf6kVlGC0vH3zPw+6AGOb+v0IH/Tb6k60CnLeHc vQ5My0PhQZNqF9dayTNhz5r3K70LxmXeOiBLOm0eDd58/FC1wJKeBIYk8tgbfw4X1x EsrPwItZhR61CXhtm7RH6Rymocmwonz+SxYNmQ1pnrqGf/xieMvrFFuSRx2Wk+sgde utBHR/Om0c1hg== To: Christopher Baines References: <9fe1701f-d78f-ba3a-37eb-64417337a55b@cock.li> <20171013223729.2605f33c@cbaines.net> <7462cec0-7d33-f2a3-1bd7-92454d690b0b@cock.li> <20171102191708.0cf85810@cbaines.net> <145a6af6-bf20-c6e3-f314-009a17239f89@cock.li> <874loz7dw7.fsf@cbaines.net> From: nee Message-ID: <0c7cab39-a15e-c8cf-36f5-f6d60d2ba59e@cock.li> Date: Mon, 11 Dec 2017 19:19:10 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.5.0 MIME-Version: 1.0 In-Reply-To: <874loz7dw7.fsf@cbaines.net> Content-Type: text/plain; charset=utf-8 Content-Language: en-GB Content-Transfer-Encoding: 8bit X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 28769 Cc: 28769@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) Am 09.12.2017 um 23:08 schrieb Christopher Baines: > I've attached some changes that I thought would be good when I was > looking through this. To give a rough summary: > > - Minor improvements to the docs, either content, markup or formatting. > - Removing trailing whitespace. > - Removing the changes to the nginx-service, in favour of changing the > default socket group. > - Change some indentation to avoid long lines. > > By changing the default socket group, the system test passes, even > without the changes to the nginx service. I think this is a bit better, > and while it's definately not perfect, I think it would be ok to merge > with this change. > Looks all good to me. Thanks for all these style fixes. > To also try and move the first patch forward, I've submitted that within > #29629, with an additional patch to get other services using > version-major. > Thanks, good to see it used at some other spots already. > It would be good to get your thoughts on the changes in the attached > patch, and then if you could send an updated set of patches, that would > be great. As far as I remember, the changes to the nginx service were > the only thing I felt needed addressing before merging this. The changes look good to me. I have no edits to add, imo the patches can be squashed merged. From debbugs-submit-bounces@debbugs.gnu.org Tue Dec 12 16:41:50 2017 Received: (at 28769-done) by debbugs.gnu.org; 12 Dec 2017 21:41:51 +0000 Received: from localhost ([127.0.0.1]:59012 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eOsJC-0005wY-Nt for submit@debbugs.gnu.org; Tue, 12 Dec 2017 16:41:50 -0500 Received: from li622-129.members.linode.com ([212.71.249.129]:60466 helo=mira.cbaines.net) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eOsJA-0005wP-OG for 28769-done@debbugs.gnu.org; Tue, 12 Dec 2017 16:41:49 -0500 Received: by mira.cbaines.net (Postfix, from userid 113) id 81ACB13E8D8; Tue, 12 Dec 2017 21:41:46 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00, T_FRT_COCK,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from localhost (cpc102582-walt20-2-0-cust14.13-2.cable.virginm.net [86.27.34.15]) by mira.cbaines.net (Postfix) with ESMTPSA id 4048513E8D7; Tue, 12 Dec 2017 21:41:45 +0000 (GMT) Received: from giedi (localhost [127.0.0.1]) by localhost (OpenSMTPD) with ESMTP id 41796956; Tue, 12 Dec 2017 21:41:44 +0000 (UTC) References: <9fe1701f-d78f-ba3a-37eb-64417337a55b@cock.li> <20171013223729.2605f33c@cbaines.net> <7462cec0-7d33-f2a3-1bd7-92454d690b0b@cock.li> <20171102191708.0cf85810@cbaines.net> <145a6af6-bf20-c6e3-f314-009a17239f89@cock.li> <874loz7dw7.fsf@cbaines.net> <0c7cab39-a15e-c8cf-36f5-f6d60d2ba59e@cock.li> User-agent: mu4e 0.9.18; emacs 25.3.1 From: Christopher Baines To: nee Subject: Re: [bug#28769] [PATCH] gnu: services: Add php-fpm. In-reply-to: <0c7cab39-a15e-c8cf-36f5-f6d60d2ba59e@cock.li> Date: Tue, 12 Dec 2017 21:41:41 +0000 Message-ID: <87vahb62ui.fsf@cbaines.net> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 28769-done Cc: 28769-done@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) --=-=-= Content-Type: text/plain Content-Transfer-Encoding: quoted-printable nee writes: > Am 09.12.2017 um 23:08 schrieb Christopher Baines: >> I've attached some changes that I thought would be good when I was >> looking through this. To give a rough summary: >>=20 >> - Minor improvements to the docs, either content, markup or formatting. >> - Removing trailing whitespace. >> - Removing the changes to the nginx-service, in favour of changing the >> default socket group. >> - Change some indentation to avoid long lines. >>=20 >> By changing the default socket group, the system test passes, even >> without the changes to the nginx service. I think this is a bit better, >> and while it's definately not perfect, I think it would be ok to merge >> with this change. >>=20 > Looks all good to me. Thanks for all these style fixes. > >> To also try and move the first patch forward, I've submitted that within >> #29629, with an additional patch to get other services using >> version-major. >>=20 > Thanks, good to see it used at some other spots already. > >> It would be good to get your thoughts on the changes in the attached >> patch, and then if you could send an updated set of patches, that would >> be great. As far as I remember, the changes to the nginx service were >> the only thing I felt needed addressing before merging this. > > The changes look good to me. > I have no edits to add, imo the patches can be squashed merged. Great, I've now rebased and pushed this. Good job :) --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQKTBAEBCgB9FiEEPonu50WOcg2XVOCyXiijOwuE9XcFAlowTRVfFIAAAAAALgAo aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldDNF ODlFRUU3NDU4RTcyMEQ5NzU0RTBCMjVFMjhBMzNCMEI4NEY1NzcACgkQXiijOwuE 9XfpyRAAuTGDESUDk72w+HNF1h1VoxyIOaq0zsvYvWbZo76l/VqQwAWk20T1obbf FNQc9mA4Ylzz4OQ7m622oHjy5krQIPgi/U7ko3GzTIoX+u0EVQyyBAPfR8Sd9i4L tHnKbdPjECyORr+FxCFflc8Ms5mmlAztxI0SZTTkpDbeSLoain4Owh0j1uSrLnL1 xwoQ/PtyuXYWZHX4i+M1gVUXb89VuvhWFlydnYB/8DA9RVFYkQ/OG/UsHAGEJP6k rFngf7mzzUrevIp2YtjXVlNn2Vgvofw1JWi9VnRoNhyYx0dWYbz0dEbqNnWShQit 746Z5dCl1sOUHR9vetyms9rwZ7f7xZfUildHYngdPcpU1c7fr9V+L9u/o007Q/7f jNqSsnSeAyqQpuujovaiEHFY8eFoe9N8dru1L5wp8xWaHcu11BTYYebmEPg1RoIx XURbaAUzHY38gMqymPImUMtnyqJ3WIEMH2B7Tk939fzrtR3XGTLw+JEV57KBw9Rk nTe8sBpbxjbc476zKWpBKFWkhMOzIx918VXfbsHLupFlp/w1zmME9ZB8N0ktLF6n Gag4kCo/MrP6jxQGjTCuq2SkG4dSziXlc8/ujIt2EcRPuKtdLVLNXxUyzxLlerjt bzg4aQvF/GCx2h0PpwotH+u8lDHINgctw+PYt1VtLq/gIRrDmK4= =C1v7 -----END PGP SIGNATURE----- --=-=-=-- From unknown Sat Jun 21 10:46:48 2025 Received: (at fakecontrol) by fakecontrolmessage; To: internal_control@debbugs.gnu.org From: Debbugs Internal Request Subject: Internal Control Message-Id: bug archived. Date: Wed, 10 Jan 2018 12:24:05 +0000 User-Agent: Fakemail v42.6.9 # This is a fake control message. # # The action: # bug archived. thanks # This fakemail brought to you by your local debbugs # administrator