Apache – PHP-FPM (FastCGI Process Manager)

Apache – PHP-FPM (FastCGI Process Manager)

Last Updated on 2025-02-03 22:12 by Sture

Consider switching to php-fpm and mod_fast_cgi as per Apache httpd project
recommendation. See https://cwiki.apache.org/confluence/display/HTTPD/PHP-FPM

Requirement:

Prevent PHP from running arbitrary code by mistake with:

user@freebsdsrv:~ $ sudo sed -i -e 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g' /usr/local/etc/php.ini && cat /usr/local/etc/php.ini | grep "fix_pathinfo=" [enter]
cgi.fix_pathinfo=0
user@freebsdsrv:~ $

PHP-FPM (FastCGI Process Manager) is a web tool used to speed up a website’s performance. It is much faster than traditional CGI-based methods and can handle tremendous loads simultaneously.

View the installed PHP-FPM version on your server.

user@freebsdsrv:~ $ php-fpm -v [enter]
PHP 8.3.15 (fpm-fcgi) (built: Jan 30 2025 02:19:24)
Copyright (c) The PHP Group
Zend Engine v4.3.15, Copyright (c) Zend Technologies
    with Zend OPcache v8.3.15, Copyright (c), by Zend Technologies
user@freebsdsrv:~ $

Enable the PHP-FPM service to start automatically at boot time.

user@freebsdsrv:~ $ sudo sysrc php_fpm_enable="YES" [enter]
php_fpm_enable:  -> YES
user@freebsdsrv:~ $

Configure PHP-FPM to use a UNIX socket instead of a TCP with:

user@freebsdsrv:~ $ sudo sed -i -e 's/127.0.0.1:9000/\/var\/run\/php-fpm.sock/g' /usr/local/etc/php-fpm.d/www.conf && cat /usr/local/etc/php-fpm.d/www.conf | grep "php-fpm.sock" [enter]
listen = /var/run/php-fpm.sock
user@freebsdsrv:~ $

Set permissions for use of the UNIX socket with:

user@freebsdsrv:~ $ sudo sed -i -e 's/;listen.owner/listen.owner/g' /usr/local/etc/php-fpm.d/www.conf && cat /usr/local/etc/php-fpm.d/www.conf | grep "listen.owner =" [enter]
listen.owner = www
user@freebsdsrv:~ $
user@freebsdsrv:~ $ sudo sed -i -e 's/;listen.group/listen.group/g' /usr/local/etc/php-fpm.d/www.conf && cat /usr/local/etc/php-fpm.d/www.conf | grep "listen.group =" [enter]
listen.group = www
user@freebsdsrv:~ $
user@freebsdsrv:~ $ sudo sed -i -e 's/;listen.mode/listen.mode/g' /usr/local/etc/php-fpm.d/www.conf && cat /usr/local/etc/php-fpm.d/www.conf | grep "listen.mode =" [enter]
listen.mode = 0660
user@freebsdsrv:~ $

Display the changed settings in with:

user@freebsdsrv:~ $ head -n 60 /usr/local/etc/php-fpm.d/www.conf [enter]
; Start a new pool named 'www'.
; the variable $pool can be used in any directive and will be replaced by the
; pool name ('www' here)
[www]

; Per pool prefix
; It only applies on the following directives:
; - 'access.log'
; - 'slowlog'
; - 'listen' (unixsocket)
; - 'chroot'
; - 'chdir'
; - 'php_values'
; - 'php_admin_values'
; When not set, the global prefix (or /usr/local) applies instead.
; Note: This directive can also be relative to the global prefix.
; Default Value: none
;prefix = /path/to/pools/$pool

; Unix user/group of the child processes. This can be used only if the master
; process running user is root. It is set after the child process is created.
; The user and group can be specified either by their name or by their numeric
; IDs.
; Note: If the user is root, the executable needs to be started with
;       --allow-to-run-as-root option to work.
; Default Values: The user is set to master process running user by default.
;                 If the group is not set, the user's group is used.
user = www
group = www

; The address on which to accept FastCGI requests.
; Valid syntaxes are:
;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific IPv4 address on
;                            a specific port;
;   '0.0.0.0:port'         - to listen on a TCP socket to all IPv4 addresses on
;                            a specific port;
;   '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
;                            a specific port;
;   'port'                 - to listen on a TCP socket to all addresses
;                            (IPv6 and IPv4-mapped) on a specific port;
;                            Note: IPv4-mapped addresses are disabled by-default in
;                                  FreeBSD for security reasons;
;   '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = /var/run/php-fpm.sock

; Set listen(2) backlog.
; Default Value: 511 (-1 on Linux, FreeBSD and OpenBSD)
;listen.backlog = 511

; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server. Many
; BSD-derived systems allow connections regardless of permissions. The owner
; and group can be specified either by name or by their numeric IDs.
; Default Values: Owner is set to the master process running user. If the group
;                 is not set, the owner's group is used. Mode is set to 0660.
listen.owner = www
listen.group = www
listen.mode = 0660

user@freebsdsrv:~ $

N.B.: Critical settings are displayed in bold!

Start PHP-FPM

Start the PHP-FPM service with:

user@freebsdsrv:~ $ sudo service php_fpm start [enter]
Performing sanity check on php-fpm configuration:
[09-Aug-2024 23:20:44] NOTICE: configuration file /usr/local/etc/php-fpm.conf test is successful
Starting php_fpm.
user@freebsdsrv:~ $

..and then restart Nginx so it loads the latest configuration changes incorporating the PHP module:

Configure Apache to load the socache_shmcb modules, uncomment the line, LoadModule proxy_module libexec/apache24/mod_proxy.so and verify the change with:

user@freebsdsrv:~ $ sudo sed -i -e '/mod_proxy.so/s/#LoadModule/LoadModule/' /usr/local/etc/apache24/httpd.conf ; cat /usr/local/etc/apache24/httpd.conf | grep "mod_proxy.so" [enter]
LoadModule proxy_module libexec/apache24/mod_proxy.so
user@freebsdsrv:~ $

Configure Apache to load the mod_proxy_fcgi.so, uncomment the line, LoadModule proxy_module libexec/apache24/mod_proxy_fcgi.so and verify the change with:

user@freebsdsrv:~ $ sudo sed -i -e '/mod_proxy_fcgi.so/s/#LoadModule/LoadModule/' /usr/local/etc/apache24/httpd.conf ; cat /usr/local/etc/apache24/httpd.conf | grep "mod_proxy_fcgi.so" [enter]
LoadModule proxy_module libexec/apache24/mod_proxy_fcgi.so
user@freebsdsrv:~ $
user@freebsdsrv:~ $ sudo ee /usr/local/etc/apache24/Includes/php.conf [enter]

…and update as in thi example:

<IfModule dir_module>
         DirectoryIndex index.php index.html
         <FilesMatch "\.php$">
                SetHandler "proxy:unix:/var/run/php-fpm.sock|fcgi://127.0.0.1/"
         </FilesMatch>
         <FilesMatch "\.phps$">
                SetHandler application/x-httpd-php-source
         </FilesMatch>
</IfModule>
user@freebsdsrv:~ $ sudo service apache24 restart [enter]
Performing sanity check on apache24 configuration:
Syntax OK
Stopping apache24.
Waiting for PIDS: 42550.
Performing sanity check on apache24 configuration:
Syntax OK
Starting apache24.
user@freebsdsrv:~ $

Verify Configuration

In order to check that the configuration changes have been applied you’ll run some tests. The first one will check what multi-processing module Apache HTTP is using. The second will verify that PHP is using the FPM manager.

Check the Apache HTTP server by running the following command:

user@freebsdsrv:~ $ sudo apachectl -M | grep 'mpm' [enter]
mpm_event_module (shared)
user@freebsdsrv:~ $

Repeat the same for the proxy module and FastCGI:

user@freebsdsrv:~ $ sudo apachectl -M | grep 'proxy' [enter]
proxy_module (shared)
proxy_fcgi_module (shared)
user@freebsdsrv:~ $

To see the entire list of the modules, you can remove the the second part of the command after -M.

Display open PHP-FPM sockets with:

user@freebsdsrv:~ $ sudo sockstat | grep "php-fpm" [enter]
www      php-fpm     1995 9   stream /var/run/php-fpm.sock
www      php-fpm     1994 9   stream /var/run/php-fpm.sock
root     php-fpm     1993 5   stream -> [1993 7]
root     php-fpm     1993 7   stream -> [1993 5]
root     php-fpm     1993 8   stream /var/run/php-fpm.sock
user@freebsdsrv:~ $

Test the FPM configuration file and display the configuration with:

user@freebsdsrv:~ $ sudo php-fpm -tt [enter]
[09-Aug-2024 23:23:29] NOTICE: [global]
[09-Aug-2024 23:23:29] NOTICE: 	pid = /var/run/php-fpm.pid
[09-Aug-2024 23:23:29] NOTICE: 	error_log = /var/log/php-fpm.log
[09-Aug-2024 23:23:29] NOTICE: 	syslog.ident = php-fpm
[09-Aug-2024 23:23:29] NOTICE: 	syslog.facility = 24
[09-Aug-2024 23:23:29] NOTICE: 	log_buffering = yes
[09-Aug-2024 23:23:29] NOTICE: 	log_level = unknown value
[09-Aug-2024 23:23:29] NOTICE: 	log_limit = 1024
[09-Aug-2024 23:23:29] NOTICE: 	emergency_restart_interval = 0s
[09-Aug-2024 23:23:29] NOTICE: 	emergency_restart_threshold = 0
[09-Aug-2024 23:23:29] NOTICE: 	process_control_timeout = 0s
[09-Aug-2024 23:23:29] NOTICE: 	process.max = 0
[09-Aug-2024 23:23:29] NOTICE: 	process.priority = undefined
[09-Aug-2024 23:23:29] NOTICE: 	daemonize = yes
[09-Aug-2024 23:23:29] NOTICE: 	rlimit_files = 0
[09-Aug-2024 23:23:29] NOTICE: 	rlimit_core = 0
[09-Aug-2024 23:23:29] NOTICE: 	events.mechanism = kqueue
[09-Aug-2024 23:23:29] NOTICE:  
[09-Aug-2024 23:23:29] NOTICE: [www]
[09-Aug-2024 23:23:29] NOTICE: 	prefix = undefined
[09-Aug-2024 23:23:29] NOTICE: 	user = www
[09-Aug-2024 23:23:29] NOTICE: 	group = www
[09-Aug-2024 23:23:29] NOTICE: 	listen = /var/run/php-fpm.sock
[09-Aug-2024 23:23:29] NOTICE: 	listen.backlog = -1
[09-Aug-2024 23:23:29] NOTICE: 	listen.owner = www
[09-Aug-2024 23:23:29] NOTICE: 	listen.group = www
[09-Aug-2024 23:23:29] NOTICE: 	listen.mode = 0660
[09-Aug-2024 23:23:29] NOTICE: 	listen.allowed_clients = undefined
[09-Aug-2024 23:23:29] NOTICE: 	listen.setfib = -1
[09-Aug-2024 23:23:29] NOTICE: 	process.priority = undefined
[09-Aug-2024 23:23:29] NOTICE: 	process.dumpable = no
[09-Aug-2024 23:23:29] NOTICE: 	pm = dynamic
[09-Aug-2024 23:23:29] NOTICE: 	pm.max_children = 5
[09-Aug-2024 23:23:29] NOTICE: 	pm.start_servers = 2
[09-Aug-2024 23:23:29] NOTICE: 	pm.min_spare_servers = 1
[09-Aug-2024 23:23:29] NOTICE: 	pm.max_spare_servers = 3
[09-Aug-2024 23:23:29] NOTICE: 	pm.max_spawn_rate = 32
[09-Aug-2024 23:23:29] NOTICE: 	pm.process_idle_timeout = 10
[09-Aug-2024 23:23:29] NOTICE: 	pm.max_requests = 0
[09-Aug-2024 23:23:29] NOTICE: 	pm.status_path = undefined
[09-Aug-2024 23:23:29] NOTICE: 	pm.status_listen = undefined
[09-Aug-2024 23:23:29] NOTICE: 	ping.path = undefined
[09-Aug-2024 23:23:29] NOTICE: 	ping.response = undefined
[09-Aug-2024 23:23:29] NOTICE: 	access.log = undefined
[09-Aug-2024 23:23:29] NOTICE: 	access.format = undefined
[09-Aug-2024 23:23:29] NOTICE: 	slowlog = undefined
[09-Aug-2024 23:23:29] NOTICE: 	request_slowlog_timeout = 0s
[09-Aug-2024 23:23:29] NOTICE: 	request_slowlog_trace_depth = 20
[09-Aug-2024 23:23:29] NOTICE: 	request_terminate_timeout = 0s
[09-Aug-2024 23:23:29] NOTICE: 	request_terminate_timeout_track_finished = no
[09-Aug-2024 23:23:29] NOTICE: 	rlimit_files = 0
[09-Aug-2024 23:23:29] NOTICE: 	rlimit_core = 0
[09-Aug-2024 23:23:29] NOTICE: 	chroot = undefined
[09-Aug-2024 23:23:29] NOTICE: 	chdir = undefined
[09-Aug-2024 23:23:29] NOTICE: 	catch_workers_output = no
[09-Aug-2024 23:23:29] NOTICE: 	decorate_workers_output = yes
[09-Aug-2024 23:23:29] NOTICE: 	clear_env = yes
[09-Aug-2024 23:23:29] NOTICE: 	security.limit_extensions = .php .phar
[09-Aug-2024 23:23:29] NOTICE:  
[09-Aug-2024 23:23:29] NOTICE: configuration file /usr/local/etc/php-fpm.conf test is successful
user@freebsdsrv:~ $

Check if PHP is using the FastCGI Process Manager by pointing your browser to: https://192.168.1.50/info.php.

N.B.: The Server API entry will be FPM/FastCGI.

More Information

Apache.org: PHP-FMP.

Comments are closed.