How to set up PHP-FPM¶
As mentioned on the official website, PHP-FPM (FastCGI Process Manager) is is an alternative PHP FastCGI implementation with some additional features (mostly) useful for heavy-loaded sites.
It allows PHP to run as its own process under its own user, separate from Apache, unlike
It also makes it possible to use multiple PHP versions from the same Apache setup.
In order to use
php-fpm to serve a website, follow the steps below.
You will need to have one system service for each version of
php-fpm you may want to run concurrently (e.g. PHP5 and PHP7).
The SysV-style init script is bundled with your PHP.
For instance, for a
phpbrew-based installation of PHP 7.2.15 in
sudo cp /opt/phpbrew/build/php-7.2.15/sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm-7.2.15 sudo chmod +x /etc/init.d/php-fpm-7.2.15
You may want to tweak the code of the script so it prints
php-fpm-7.2.15 rather than just
php-fpm, but it is not necessary.
Before you can run this, you have to tweak the
php-fpm.conf file, which is usually close to where the relevant
phpbrew-based install, it would be in
Make sure you uncomment the line mentioning the
pid variable, so that a PID file is created.
You will also need to ensure that both
group are set to the appropriate one in the
This would be
php-fpm in our CentOS-based servers.
It would be even better if you used an app-specific user, to isolate PHP applications from each other.
Once these tweaks are ready, start the service manually and check it started correctly with:
sudo /etc/init.d/php-fpm-7.2.15 start sudo /etc/init.d/php-fpm-7.2.15 status
Make sure you register the service to be started on boot. In CentOS 6, this would be done with:
sudo /sbin/chkconfig php-fpm-7.2.15 on
Reloading the PHP OPCACHE¶
When a new version of a website is deployed via FPM, PHP does not automatically flush its OPCODE cache, which means that users will see the old version of the application.
In order to force this to happen, the following needs to be added to the
# Ensure PHP FPM is reloaded (picks up new code) if test -x /usr/sbin/service; then sudo -n /usr/sbin/service php7.2-fpm reload fi
This means that
gitlab-runner, which runs as an unprivileged user, needs to call
To make this happen, on Ubuntu or CentOS servers, run
sudo visudo and add this to the
gitlab-runner ALL = (root) NOPASSWD: /usr/sbin/service php7.2-fpm reload
Note that the command itself is run with
sudo -n, so it will never prompt for a password and just fail if it were to ask for a password.
See this guide for more details on editing
sudoers on Ubuntu and CentOS.
Apache virtual host (UNIX socket-based)¶
To switch from
php-fpm, go to your
<VirtualHost> and change it to use
ProxyPassMatch for any
ProxyPassMatch ^/(.*\.php(/.*)?)$ unix:/opt/phpbrew/php/php-7.2.15/var/run/php-fpm.sock|fcgi://localhost/path/to/document/root
This must be done at the
<VirtualHost> level: it cannot be done from a
Apache virtual host (TCP socket-based)¶
On SELinux-happy environments (e.g. CentOS), it may be easier to tweak the
php-fpm.d/www.conf file to listen on a TCP port:
listen = 127.0.0.1:port
You can then tell Apache to use that TCP socket, with a slightly different syntax.
By the way, this syntax can be used to forward specific subfolders in a
<VirtualHost> to specific versions of PHP (as done in the Industry Club website):
ProxyPassMatch "^/folder/(.*\.php(/.*)?)$" fcgi://127.0.0.1:9007/path/to/folder/$1