PHP-FPM

How is PHP-FPM installed ?

PHP PHP-FPM is source compiled with some additional PHP extensions configured out of the box including using the MySQL Native Driver extension (mysqlnd overview). Read FAQ as to why source compiled vs RPM.

The default configure options are as follows (on 64bit OS):

../configure  --enable-fpm --enable-intl --enable-pcntl --with-mcrypt --with-snmp --with-mhash --with-zlib --with-gettext --enable-exif --enable-zip --with-bz2 --enable-soap --enable-sockets --enable-sysvmsg --enable-sysvsem --enable-sysvshm --enable-shmop --with-pear --enable-mbstring --with-openssl --with-mysql=mysqlnd --with-libdir=lib64 --with-mysqli=mysqlnd --with-mysql-sock=/var/lib/mysql/mysql.sock --with-curl --with-gd --with-xmlrpc --enable-bcmath --enable-calendar --enable-ftp --enable-gd-native-ttf --with-freetype-dir=/usr --with-jpeg-dir=/usr --with-png-dir=/usr --with-xpm-dir=/usr --with-vpx-dir=/usr --with-t1lib=/usr --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 --disable-fileinfo --with-config-file-scan-dir=/etc/centminmod/php.d

If you need to enable FILEINFO, just edit centmin.sh as outlined here. Centmin Mod 1.2.3-eva2000.08+ and higher 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 5.4.x instead of PHP 5.5.x or 5.6.x or PHP 7 ?

Centmin Mod releases are tested from fresh installs as well as upgrades with latest PHP (php-fpm) 5.3.x, 5.4.x, 5.5.x and 5.6.x versions as well as native support for PHP 7. But PHP (php-fpm) 5.4.x is the default installed PHP version for best PHP script compatibility. Not all PHP scripts out there are coded to support PHP 5.5.x or 5.6.x or PHP 7.0, so I've left the choice of PHP versions up to the end user. You can choose which version of PHP to use yourself and it would be up to you to make sure your PHP scripts support the chosen PHP version. You can always downgrade to PHP 5.3.x later on and upgrade again to PHP 5.4 - 5.6 or PHP 7.0.x whenever you want.

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

There are 2 methods you can choose to use PHP (php-fpm) 5.5.x or 5.6.x:

Method 1.
Start fresh Centmin Mod install with latest PHP 5.5.x or 5.6.x version by editing centmin.sh and changing the PHP_VERSION variable to appropriate PHP version. So to go from PHP 5.4.45 to PHP 5.5.38, you'd edit centmin.sh BEFORE running fresh installation and change the variable

from

  PHP_VERSION='5.4.45'          # Use this version of PHP

to

  PHP_VERSION='5.5.38'          # Use this version of PHP

Currently, at this time PHP 7.0.9 is latest version so PHP_VERSION='7.0.9' would be the name used or specified via centmin.sh menu option 5 PHP upgrading routine. If you also want to switch from APC Cache 3.1.13 or APC Cache 3.1.15-dev (used for PHP 5.5+) to Zend OpCache, you can also set in centmin.sh the variable ZOPCACHEDFT='y' prior to initial centmin.sh install run.

  ZOPCACHEDFT='y'

If you want these changes to persistent on subsequent Centmin Mod code updates instead of having to re-edit them everytime, you can also setup a persistent /etc/centminmod/custom_config.inc file as outlined here.

Then do the first time fresh install as per How to Install Centmin Mod Guide

Method 2.
Upgrading an existing Centmin Mod install base from PHP 5.4.x to PHP 5.5.x or 5.6.x by running centmin.sh script and selecting menu option #5 and specifying the PHP version you want to upgrade (or downgrade to) i.e. specify PHP 5.4.45 or PHP 5.5.38 or PHP 5.6.24. More specific upgrade details outlined below. You can read the PHP 5.6.0 upgrade thread for more details too.

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 5.5.x upgrades.

If you are upgrading a server which already previously had Centmin Mod installed, you DO NOT need to run option #1 (in fact as of Centmin Mod v1.2.2-eva2000.14 it will be impossible to run option #1 as the script will detect previous install of Centmin Mod and abort the script), instead run option #4 and then #5 for upgrading Nginx web server and upgrading PHP. You only need to run these if you upgrading to new Nginx or PHP version. If your existing Centmin Mod install has the same versions for Nginx and PHP, no need to even run those menu options.

Right way to upgrade PHP PHP-FPM

Menu option #5 will upgrade your 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.

Prior to Centmin Mod 1.2.3-eva2000.07 stable release, upgrading PHP involved some additional steps if you had installed any of the following PHP extensions, Xcache, APC, Suhosin, FFMPEG, Memcache or generally any extension which required you to manually load a *.so file into php.ini. The reason why is the PHP upgrade routine will backup your existing php.ini which is at /usr/local/lib/php.ini and save backup to /usr/local/lib/php.ini-oldversion_timestamp and then overwrite that php.ini file with latest php.ini supplied by PHP tarbal download package. However, with Centmin Mod 1.2.3-eva2000.07 and higher versions, this is usually no longer required as the upgrade routine automatically detects previously compiled PHP extensions and auto recompiles them on major PHP upgrades only i.e. PHP 5.4 to 5.5 or 5.6. It will skip auto recompiles for minor PHP upgrades i.e. PHP 5.5.16 to 5.5.17.

The PHP upgrade process will then do a DIFF comparison check between new /usr/local/lib/php.ini and saved backup at /usr/local/lib/php.ini-oldversion_timestamp and display all the changes and differences between the file. There's a 60 second delay on the screen so you can use that opportunity to copy or note the changes for your own records. Usually, the changes will highlight what PHP extensions were installed previously and what is missing in the new php.ini.

Prior to Centmin Mod 1.2.3-eva2000.07 stable release, all you had to do after PHP upgrade was to re-install those PHP extensions via menu options listed below - for Suhosin and FFMPEG install is fine. However, with Centmin Mod 1.2.3-eva2000.07 and higher versions, this is usually no longer required unless there are issues requiring manual recompile via menu options outlined below:

  • 6). XCache Re-install
  • 7). APC Cache Re-install
  • 10). Memcached Server Re-install (this also updates your libevent version)
  • 15). Install/Re-install imagick PHP Extension
  • 18). Suhosin PHP Extension install
  • 19). Install FFMPEG and FFMPEG PHP Extension

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, ImagicK, igbinary, FFMPEG and Suhosin 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'.

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)


PHP 5.5+ and higher

For Centmin Mod users wanting to try PHP 5.5+ and higher, there is one compatibility issue in that public APC Cache 3.1.13 isn't compatible. The latest APC Cache 3.1.15-dev trunk release however is compatible with PHP 5.5+.

For your own web apps you need to test for compatibility, see http://au1.php.net/manual/en/migration55.php and http://php.net/ChangeLog-5.php#5.5.0

The current Centmin Mod release can now automatically detect if you are using or upgrading to PHP 5.5+ and higher versions and auto switch to use the APC Cache 3.1.15-dev trunk version which I also uploaded to Centmin Mod web site and renamed it as 3.1.13 for ease of replacement. There is no longer any need to manually download and use APC Cache 3.1.15-dev. However, if you need to manually do this for whatever reason, the following steps in SSH telnet are needed to use PHP 5.5+ and higher for APC Cache 3.1.15-dev trunk release (which is renamed to APC-3.1.13).:

  1. Remove old APC Cache tarball and download APC 3.1.5-dev
    cd /svr-setup
    rm -rf APC-3.1.13*
    wget -c http://centmin.sh/centminmodparts/apc/php550/APC-3.1.13.tgz
    
  2. Run centmin.sh
    cd /usr/local/src/centmin-v1.2.3mod
    ./centmin.sh
    
  3. Select menu option #5 to upgrade PHP to version = 5.5.28
  4. Select menu option #7 to re-install APC Cache specify version = 3.1.13
  5. If you had memcached installed or imagick PHP extension, then run menu options #10 and #15 to re-install them for PHP 5.5.28

Example of working PHP 5.5.0 + APC Cache 3.1.15-dev trunk