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:
- Apache -PHP Scripting Language (8.3.X Branch) must be performed before this step.
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.