PHP-FPM

How is PHP-FPM installed ?

PHP PHP-FPM is source compiled with some additional PHP extensions configured out of the box. Read FAQ as to why source compiled vs RPM.

Example PHP 8.3.9 configuration options on AlmaLinux:

php-config --configure-options
--enable-fpm --enable-opcache --enable-intl --enable-pcntl --with-mcrypt --with-snmp --enable-embed=shared --with-mhash --with-zlib --with-gettext --enable-exif --with-zip --with-libzip --with-bz2 --enable-soap --enable-sockets --enable-sysvmsg --enable-sysvsem --enable-sysvshm --with-mysql-sock=/var/lib/mysql/mysql.sock --with-curl --enable-gd --with-xmlrpc --enable-bcmath --enable-calendar --enable-ftp --enable-gd-native-ttf --with-freetype --with-jpeg --with-png-dir=/usr --with-xpm --with-webp --with-t1lib=/usr --enable-shmop --with-pear --enable-mbstring --with-openssl --with-mysql=mysqlnd --with-libdir=lib64 --with-mysqli=mysqlnd --enable-pdo --with-pdo-sqlite --with-pdo-mysql=mysqlnd --enable-inline-optimization --with-imap --with-imap-ssl --with-kerberos --with-readline --with-libedit --with-gmp --with-pspell --with-tidy --with-enchant --with-fpm-user=nginx --with-fpm-group=nginx --with-ldap --with-ldap-sasl --with-password-argon2 --with-sodium=/usr/local --with-pic --with-config-file-scan-dir=/etc/centminmod/php.d --with-fpm-systemd --with-ffi --with-xsl PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig: PNG_CFLAGS=-I/usr/include PNG_LIBS=-L/usr/lib64 -lpng16 ICU_CFLAGS=-fPIC ICU_LIBS=-L/usr/lib64 -licuio -licui18n -licuuc -licudata ONIG_CFLAGS=-I/usr/include ONIG_LIBS=-L/usr/lib64 -lonig LIBSODIUM_CFLAGS=-fPIC LIBSODIUM_LIBS=-L/usr/local/lib64 -lsodium ARGON2_CFLAGS=-I/usr/local/include ARGON2_LIBS=-L/usr/local/lib64 -largon2 LIBZIP_CFLAGS=-fPIC LIBZIP_LIBS=-L/usr/local/lib64 -lzip

If you need to enable FILEINFO, just edit centmin.sh as outlined here. Centmin Mod auto detects if you have enough memory available and auto enables FILEINFO if there is enough memory available.


Customising php.ini settings

The default php.ini location is at /usr/local/lib/php.ini. However, PHP upgrades via centmin.sh menu option 5 can overwrite that. So it's best to set aside your php.ini level customisations in a separate *.ini file. Centmin Mod by default has a custom file at /etc/centminmod/php.d/a_customphp.ini which has some tweaks to PHP settings already added by default. You can add custom settings to /etc/centminmod/php.d/a_customphp.ini however, they can be also overwritten if future Centmin Mod updates adjust or add tweaks which are automated on PHP-FPM upgrades. So you can instead create a second custom file with naming convention alphabetically below that of /etc/centminmod/php.d/a_customphp.ini i.e. /etc/centminmod/php.d/b_customphp.ini.

Default /etc/centminmod/php.d/a_customphp.ini contents. Note ;always_populate_raw_post_data=-1 is auto uncommented (remove semi-colon ;) when PHP 5.6+ is detected only.

date.timezone = UTC
max_execution_time = 60
short_open_tag = On
realpath_cache_size = 1024k
realpath_cache_ttl = 14400
upload_max_filesize = 40M
memory_limit = 160M
post_max_size = 40M
expose_php = Off
mail.add_x_header = Off
max_input_nesting_level = 128
max_input_vars = 2000
mysqlnd.net_cmd_buffer_size = 16384
;always_populate_raw_post_data=-1

You can add your own custom settings to a newly created file at /etc/centminmod/php.d/b_customphp.ini i.e. double default max_execution_time from 60 to 120. PHP-FPM will process those in a specific alpha-numeric order where later ini files override the former.

max_execution_time = 120

Then restart PHP-FPM service via either command shortcut or full service restart command

fpmrestart

or

service php-fpm restart

Confirming changes are in effect by looking at phpinfo file. Centmin Mod sets this up on main hostname with randomised prefix unqiue to each Centmin Mod install. You can rename this file, delete it or password protect or IP address restrict it if you want. In below example, the install created phpinfo file at /usr/local/nginx/html/417911c9_phpi.php which would be accesible online via yourmainhostname.com/417911c9_phpi.php or localhost/417911c9_phpi.php.

ls -lah /usr/local/nginx/html | grep phpi                          
-rw-r--r-- 1 nginx nginx   20 Jul 28 11:31 417911c9_phpi.php

You don't need to move out of SSH session to do a simple check - use lynx command grep can confirm the changes.

before

lynx -dump localhost/417911c9_phpi.php | grep max_execution_time    
   max_execution_time 60 60

after

lynx -dump localhost/417911c9_phpi.php | grep max_execution_time    
   max_execution_time 120 120

Typing the command php --ini, will output the list of *.ini files PHP-FPM has detected and the order in which they are processed.

php --ini

default before custom /etc/centminmod/php.d/b_customphp.ini file added

php --ini
Configuration File (php.ini) Path: /usr/local/lib
Loaded Configuration File:         /usr/local/lib/php.ini
Scan for additional .ini files in: /etc/centminmod/php.d
Additional .ini files parsed:      /etc/centminmod/php.d/a_customphp.ini,
/etc/centminmod/php.d/curlcainfo.ini,
/etc/centminmod/php.d/geoip.ini,
/etc/centminmod/php.d/igbinary.ini,
/etc/centminmod/php.d/imagick.ini,
/etc/centminmod/php.d/memcache.ini,
/etc/centminmod/php.d/memcached.ini,
/etc/centminmod/php.d/mongodb.ini,
/etc/centminmod/php.d/redis.ini,
/etc/centminmod/php.d/zendopcache.ini

after custom /etc/centminmod/php.d/b_customphp.ini file added and PHP-FPM service restarted

php --ini
Configuration File (php.ini) Path: /usr/local/lib
Loaded Configuration File:         /usr/local/lib/php.ini
Scan for additional .ini files in: /etc/centminmod/php.d
Additional .ini files parsed:      /etc/centminmod/php.d/a_customphp.ini,
/etc/centminmod/php.d/b_customphp.ini,
/etc/centminmod/php.d/curlcainfo.ini,
/etc/centminmod/php.d/geoip.ini,
/etc/centminmod/php.d/igbinary.ini,
/etc/centminmod/php.d/imagick.ini,
/etc/centminmod/php.d/memcache.ini,
/etc/centminmod/php.d/memcached.ini,
/etc/centminmod/php.d/mongodb.ini,
/etc/centminmod/php.d/redis.ini,
/etc/centminmod/php.d/zendopcache.ini


PHP Security Lock Down

To further lock down PHP-FPM security you can disable some PHP functions. However, check with your respective web app PHP developers whehther those PHP functions are needed otherwise disabling these PHP functions can break your PHP web app software.

At very bottom of PHP-FPM config file at /usr/local/etc/php-fpm.conf (command shortcut in SSH = fpmconf), just after PHP error log definition you will find a line like below (if using Centmin Mod 1.2.3-eva2000.08 beta) or if using Centmin Mod 1.2.3-eva2000.07 stable release, you need to add that line right after the PHP error log definition. PHP-FPM config file edit is preferred over php.ini file edit as it will survive subsequent PHP-FPM upgrades where new php.ini files are put in place.

  php_admin_value[error_log] = /var/log/php-fpm/www-php.error.log
  php_admin_value[disable_functions] = shell_exec

You can extend the number of PHP functions to disable to further lock down and secure your PHP web apps provided your PHP web apps do not rely on and use such PHP functions.

For example.

  php_admin_value[disable_functions] = show_source, system, shell_exec, passthru, exec, popen, proc_open

Then after editing /usr/local/etc/php-fpm.conf restart PHP-FPM service

  service php-fpm restart

or

  fpmrestart


open_basedir restrictions

For PHP web apps, you may run into the error message open_basedir restriction in effect which is a form of PHP security that Centmin Mod 1.2.3-eva2000.08+ and higher has enabled by default. FAQ item 26 shows you how to disable open_basedir globally or for just one Nginx vhost site. The relevant line is the 9th line in /usr/local/nginx/conf/php.conf. This line locks you to each Nginx vhost's document web root

fastcgi_param PHP_ADMIN_VALUE open_basedir=$document_root/:/usr/local/lib/php/:/tmp/;


Why default to PHP 8.0.x instead of PHP 8.1.x, 8.2.x or 8.3.x ?

Centmin Mod 131.00stable or 140.00beta01 or higher releases are tested from fresh installs as well as upgrades with latest PHP (php-fpm) versions. For AlmaLinux/Rocky Linux 8, PHP 8.0 is the default and for AlmaLinux/Rocky Linux 9, PHP 8.1 is the default. Or you can use a different PHP default version Centmin Mod installer. Or you can switch between PHP versions via centmin.sh menu option 5 and entering your desired PHP version when prompted. Centmin Mod latest versions also support a SSH command line option: getphpver which will list the latest PHP version for each PHP major branch so you can be informed of latest PHP version to enter when prompted.

While the getphpver command lists PHP 5.5-7.1 versions, these are no longer supported in AlmaLinux or Rocky Linux 8/9 operating systems. AlmaLinux/Rocky Linux 8 minimum supported PHP version is PHP 7.2, while AlmaLinux/Rocky Linux 9 minimum supported PHP version is PHP 7.4 as Centmin Mod has backported patch support for PHP 7.4 and PHP 8.0 for EL9 operating systems as technically for EL9 operating systems, PHP 8.0 is minimum supported version due to PHP 7.4 and PHP 8.0 not natively supporting EL9's OpenSSL 3.0 crypto library.

getphpver

8.3.9
8.2.21
8.1.29
8.0.30
7.4.33
7.3.33
7.2.34
7.1.33
7.0.33
5.6.40
5.5.38

With getphpver command you can also narrow the latest PHP version output to just one PHP major version:

getphpver 83
8.3.9

getphpver 82
8.2.21

getphpver 81
8.1.29

getphpver 80
8.0.30

getphpver 74
7.4.33

getphpver 73
7.3.33

getphpver 72
7.2.34

You can also find latest PHP versions stable releases on the top right corner column on php.net.

How to edit php.ini and php-fpm configuration files ?

Centmin Mod install created command short cuts outlined here to allow you to quickly edit your /usr/local/lib/php.ini file and your /usr/local/etc/php-fpm.conf file. Full list of command shortcuts below:

  • Edit php.ini = phpedit ( /usr/local/lib/php.ini )
  • Edit my.cnf = mycnf ( /etc/my.cnf )
  • Edit php-fpm.conf = fpmconf ( /usr/local/etc/php-fpm.conf )
  • Edit nginx.conf = nginxconf ( /usr/local/nginx/conf/nginx.conf )
  • Edit (nginx) virtual.conf = vhostconf - only edits /usr/local/nginx/conf/conf.d/virtual.conf not the additional vhost domain.com.conf files added later
  • Edit (nginx) php.conf = phpinc ( /usr/local/nginx/conf/php.conf )
  • Edit (nginx) drop.conf = dropinc ( /usr/local/nginx/conf/drop.conf )
  • Edit (nginx) staticfiles.conf = statfilesinc ( /usr/local/nginx/conf/staticfiles.conf )
  • nginx stop/start/restart = ngxstop/ngxstart/ngxrestart
  • php-fpm stop/start/restart = fpmstop/fpmstart/fpmrestart
  • mysql stop/start/restart = mysqlstop/mysqlstart/mysqlrestart
  • nginx + php-fpm stop/start/restart = npstop/npstart/nprestart
  • memcached stop/start/restart = memcachedstop/memcachedstart/memcachedrestart
  • csf stop/start/restart = csfstop/csfstart/csfrestart


PHP Upgrade

Note: For PHP upgrades.

Right way to upgrade PHP PHP-FPM

You can use centmin.sh menu option 5 to upgrade, downgrade or recompile your desired PHP version to whatever version you enter at the prompt. You'll find latest PHP versions stable releases on the top right corner column on php.net or by typing SSH command: getphpver.

Example centmin.sh menu option 5 upgrade switch to PHP 8.3.9 version below:

--------------------------------------------------------
     Centmin Mod Menu 140.00beta01 centminmod.com     
--------------------------------------------------------
1).  Centmin Install
2).  Add Nginx vhost domain
3).  NSD setup domain name DNS
4).  Nginx Upgrade / Downgrade
5).  PHP Upgrade / Downgrade
6).  MySQL User Database Management
7).  Persistent Config File Management
8).  Option Being Revised (TBA)
9).  Option Being Revised (TBA)
10). Memcached Server Re-install
11). MariaDB MySQL Upgrade & Management
12). Zend OpCache Install/Re-install
13). Install/Reinstall Redis PHP Extension
14). SELinux disable
15). Install/Reinstall ImagicK PHP Extension
16). Change SSHD Port Number
17). Multi-thread compression: zstd,pigz,pbzip2,lbzip2
18). Suhosin PHP Extension install
19). Install FFMPEG and FFMPEG PHP Extension
20). NSD Install/Re-Install
21). Data Transfer
22). Add Wordpress Nginx vhost + Cache Plugin
23). Update Centmin Mod Code Base
24). Exit
--------------------------------------------------------
Enter option [ 1 - 24 ] 5
--------------------------------------------------------

PHP Upgrade/Downgrade - Would you like to continue? [y/n] y

----------------------------------------------------------------
Install which version of PHP? (i.e. 7.3.33, 7.4.33, 8.0.30, 8.1.29, 8.2.21, 8.3.9, NGDEBUG)
PHP 7.x/7.1.x/7.2.x/7.3.x is GA Stable but still may have broken PHP extensions.
NGDEBUG is PHP 8.4 dev builds minus incompatible PHP extensions
----------------------------------------------------------------

Current PHP Version: 8.4.0alpha1
Can Not Determine Latest PHP Version Installable:
8.3.9
8.2.21
8.1.29
8.0.30
7.4.33
7.3.33
7.2.34
7.1.33
7.0.33
5.6.40
5.5.38

Enter PHP Version number you want to upgrade/downgrade to: 8.3.9

Do you still want to continue? [y/n] y

----------------------------------------------------------------
existing php.ini will be backed up at /usr/local/lib/php.ini-oldversion_170724-231417
----------------------------------------------------------------

-----------------------------------------------------------------------------------------
Detected PHP 8.3 branch.
You can compile Zend OPcache (Zend Optimizer Plus+) support
as an alternative to using APC Cache or Xcache cache.
But Zend OPcache only provides PHP opcode cache and
DOESN'T do data caching, so if your web apps such as Wordpress,
Drupal or vBulletin require data caching to APC or Xcache,
it won't work with Zend OPcache.

-----------------------------------------------------------------------------------------
Do you want to use Zend OPcache [y/n] ? y

The PHP upgrade process also backs up and overwrites your existing php-fpm configuration file /usr/local/etc/php-fpm.conf to /usr/local/etc/php-fpm.conf-oldversion_timestamped. It will prompt you and ask if you want to overwrite and backup the php-fpm.conf file. This is to ensure updated php-fpm.conf changes make it into your server's php-fpm configuration.


PHP Extensions where are they loaded from ?

Centmin Mod additional PHP compiled extensions such as APC Cache, Xcache, Memcache/Memcached, Redis, ImagicK, igbinary, FFMPEG are usually loaded separately from php.ini for ease of management via the menu options. As such these PHP compiled extensions are loaded individually into their own respective *.ini files in the directory defined in centmin.sh script, CONFIGSCANBASE='/etc/centminmod'.

You can find their full paths by typing SSH command php --ini. Below is the example output for PHP 8.3.9 on AlmaLinux.

php --ini

Configuration File (php.ini) Path: /usr/local/lib
Loaded Configuration File:         /usr/local/lib/php.ini
Scan for additional .ini files in: /etc/centminmod/php.d
Additional .ini files parsed:      /etc/centminmod/php.d/a_customphp.ini,
/etc/centminmod/php.d/curlcainfo.ini,
/etc/centminmod/php.d/geoip.ini,
/etc/centminmod/php.d/igbinary.ini,
/etc/centminmod/php.d/imagick.ini,
/etc/centminmod/php.d/mailparse.ini,
/etc/centminmod/php.d/mcrypt.ini,
/etc/centminmod/php.d/memcache.ini,
/etc/centminmod/php.d/memcached.ini,
/etc/centminmod/php.d/redis.ini,
/etc/centminmod/php.d/timezonedb.ini,
/etc/centminmod/php.d/zendopcache.ini

So if you need to edit settings or manually disable a PHP extension, you can do so at the following locations (provided you have actually installed the listed PHP extension):

  • /etc/centminmod/php.d/apc.ini (edit APC memory allocation here)
  • /etc/centminmod/php.d/xcache.ini (edit Xcache memory allocation here)
  • /etc/centminmod/php.d/igbinary.ini
  • /etc/centminmod/php.d/imagick.ini
  • /etc/centminmod/php.d/memcache.ini
  • /etc/centminmod/php.d/memcached.ini
  • /etc/centminmod/php.d/suhosin.ini (older installs will have ffmpeg.so directory loaded via (/usr/local/lib/php.ini)
  • /etc/centminmod/php.d/ffmpeg.ini (older installs will have suhosin.so directory loaded via (/usr/local/lib/php.ini)
  • /etc/centminmod/php.d/zendopcache.ini (edit Zend Opcache memory allocation here)


How to enable php-fpm usage stats display ?

If you want to view status from web browser instead of within SSH telnet for your server, whitelist your ip address within /usr/local/nginx/conf/phpstatus.conf file which by default only allows 127.0.0.1. Add additional line for your ip address i.e. 111.222.333.444.

              location ~ ^/(phpstatus|phpping)$ {
                access_log          off;
                fastcgi_pass        127.0.0.1:9000;
                fastcgi_param     SCRIPT_FILENAME $fastcgi_script_name;
                include          fastcgi_params;
                allow              127.0.0.1;
                allow              111.222.333.444;
                deny                all;
            }

If you only want to access phpstatus from within your SSH telnet sessions via lynx, you need to whitelist your server IP address i.e. 123.456.789.999.

              location ~ ^/(phpstatus|phpping)$ {
                access_log          off;
                fastcgi_pass        127.0.0.1:9000;
                fastcgi_param     SCRIPT_FILENAME $fastcgi_script_name;
                include          fastcgi_params;
                allow              127.0.0.1;
                allow              123.456.789.999;
                deny                all;
            }

You need to edit /usr/local/nginx/conf/conf.d/virtual.conf and find the very first instance of these lines

include /usr/local/nginx/conf/staticfiles.conf;
include /usr/local/nginx/conf/php.conf;
#include /usr/local/nginx/conf/phpstatus.conf;
include /usr/local/nginx/conf/drop.conf;
#include /usr/local/nginx/conf/errorpage.conf;

Uncomment and enable by remove # hash in front of phpstatus.conf

So this

#include /usr/local/nginx/conf/phpstatus.conf;

becomes

include /usr/local/nginx/conf/phpstatus.conf;

save /usr/local/nginx/conf/conf.d/virtual.conf, then restart Nginx and php-fpm service.

service nginx restart
service php-fpm restart

or if you installed centmin mod shortcuts http://centmin.sh/faq.html#commandshortcuts you can use this command

nprestart

then install lynx via yum

yum -q -y install lynx

then run this command whenever you want to see php-fpm usage stats

lynx --dump  http://127.0.0.1/phpstatus

You'll get output like below

pool:                 www
process manager:      static
start time:           28/Jun/2012:21:24:51 +0400
start since:          75
accepted conn:        196
listen queue:         0
max listen queue:     0
listen queue len:     0
idle processes:       4
active processes:     1
total processes:      5
max active processes: 1
max children reached: 0

PHP Status explained:

  • pool - the name of the pool that is listening on the connected socket, as defined in the php-fpm config.
  • process manager - the method used by the process manager to control the number of child processes - either ondemand, dynamic or static - set on a per pool basis (in the php-fpm config) by the pm parameter.
  • start time - the date, time, and UTC offset corresponding to when the PHP-FPM server was started.
  • start since - the number of seconds that have elapsed since the PHP-FPM server was started (i.e. uptime).
  • accepted conn - the number of incoming requests that the PHP-FPM server has accepted; when a connection is accepted it is removed from the listen queue (displayed in real time).
  • listen queue - the current number of connections that have been initiated, but not yet accepted. If this value is non-zero it typically means that all the available server processes are currently busy, and there are no processes available to serve the next request. Raising pm.max_children (provided the server can handle it) should help keep this number low. This property follows from the fact that PHP-FPM listens via a socket (TCP or file based), and thus inherits some of the characteristics of sockets.
  • max listen queue - the maximum value the listen queue has reached since the server was started.
  • listen queue len - the upper limit on the number of connections that will be queued Once this limit is reached, subsequent connections will either be refused, or ignored. This value is set by the php-fpm per pool configuration option 'listen.backlog', which defaults to -1 (unlimited). However, this value is also limited by the system (sysctl) value 'net.core.somaxconn', which defaults to 128 on many Linux systems.
  • idle processes - the number of servers in the 'waiting to process' state (i.e. not currently serving a page). This value should fall between the pm.min_spare_servers and pm.max_spare_servers values when the process manager is dynamic. (updated once per second)
  • active processes - the number of servers current processing a page - the minimum is 1 (so even on a fully idle server, the result will be not read 0). (updated once per second)
  • total processes - the total number of server processes currently running; the sum of idle processes + active processes. If the process manager is static, this number will match pm.max_children. (updated once per second)
  • max active processes - the highest value that 'active processes' has reached since the php-fpm server started. This value should not exceed pm.max_children.
  • max children reached - the number of times that pm.max_children has been reached since the php-fpm server started (only applicable if the process manager is ondemand or dynamic)