Ubuntu 16.04 Apache 2.4 with PHP-FPM

PHP-FPM does have some advantages depending on the solution and the common path is to use Nginx with PHP-FPM. However what happens when you want to utilize the normal features of Apache, such as basics like .htaccess files, but still keep the tuning options open that come with PHP-FPM? Well, there is a module for that!

This guide is going to assume a fresh Ubuntu 16.04 server to illustrate everything from start to finish, and will assume that all sites on this server will use the same php-fpm pool.

First, installed the required packages for your web server:

[[email protected] ~]# apt-get update
[[email protected] ~]# apt-get install php7.0-fpm apache2

Now confirm or update the Apache configuration to use the mpm_event_module instead of the mpm_prefork_module:

[[email protected] ~]# a2enmod actions
[[email protected] ~]# apache2ctl -M | grep mpm
[[email protected] ~]# a2dismod mpm_prefork
[root[email protected] ~]# a2dismod mpm_worker
[[email protected] ~]# a2enmod mpm_event

Then tell Apache to send all PHP requests over to PHP-FPM by creating a new configuration file:

[[email protected] ~]# vim /etc/apache2/conf-available/php.conf
<FilesMatch \.php$>
	SetHandler "proxy:unix:/run/php/php7.0-fpm.sock|fcgi://localhost/"
</FilesMatch>

Enable the new Apache PHP configuration:

[[email protected] ~]# a2enconf php.conf

Confirm PHP-FPM is set to use sockets instead of TCP connections for performance purposes, and also confirm the following additional settings:

[[email protected] ~]# vim /etc/php/7.0/fpm/pool.d/www.conf
; listen = 127.0.0.1:9000
listen = /run/php/php7.0-fpm.sock
...
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
user = www-data
group = www-data

Enable FCGI proxy, then restart Apache and PHP-FPM to apply the changes above:

[[email protected] ~]# a2enmod proxy_fcgi
[[email protected] ~]# systemctl restart apache2
[[email protected] ~]# systemctl restart php7.0-fpm

If you are using a software firewall on the server, open ports 80/443 accordingly. This example will open them up to the world. Adjust yours accordingly:

[[email protected] ~]# ufw allow 80
[[email protected] ~]# ufw allow 443

Finally, test a site to ensure PHP is working and is using PHP-FPM by creating the file below, then visiting the page at x.x.x.x/info.php:

[[email protected] ~]# vim /var/www/html/info.php
<?php phpinfo(); ?>

And your done!

Using multiple PHP-FPM pools

What happens if you want to isolate each site to their own PHP-FPM pool instead of using a shared pool? That is easy enough to do. Assuming that you followed everything in this guide to get to this point, do the following.

First, disable the global Apache configuration for PHP:

[[email protected] ~]# a2disconf php.conf

Create a new PHP-FPM pool for this specific site and update it accordingly:

[[email protected] ~]# cp /etc/php/7.0/fpm/pool.d/www.conf /etc/php/7.0/fpm/pool.d/example.com.conf
[[email protected] ~]# vim /etc/php/7.0/fpm/pool.d/example.com.conf
; 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)
[example.com]
...
; listen = 127.0.0.1:9000
listen = /run/php/www.example.com-php7.0-fpm.sock
...
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
user = www-data
group = www-data

Then update the site’s Apache vhost to point to a new PHP-FPM pool in both the 80 and 443 stanzas. Be sure to update the socket accordingly for your site in the 2 sections below! (ie: unix:/run/php/www.example.com-php7.0-fpm.sock)

[[email protected] ~]# vim /etc/httpd/vhost.d/example.com.conf
<VirtualHost *:80>
        ServerName example.com
        ServerAlias www.example.com
        DocumentRoot /var/www/vhosts/example.com

	# Send PHP requests to php-fpm
        <FilesMatch \.php$>
                SetHandler "proxy:unix:/run/php/www.example.com-php7.0-fpm.sock|fcgi://localhost/"
        </FilesMatch>

...
<VirtualHost *:443>
        ServerName example.com
        ServerAlias www.example.com
        DocumentRoot /var/www/vhosts/example.com

	# Send PHP requests to php-fpm
        <FilesMatch \.php$>
                SetHandler "proxy:unix:/run/php/www.example.com-php7.0-fpm.sock|fcgi://localhost/"
        </FilesMatch>
...

Enable FCGI proxy, then restart Apache and PHP-FPM to apply the changes above:

[[email protected] ~]# a2enmod proxy_fcgi
[[email protected] ~]# systemctl restart php7.0-fpm
[[email protected] ~]# systemctl restart apache2

Finally, test a site to ensure PHP is working and is using PHP-FPM by creating the file below, then visiting the page at example.com/info.php:

[[email protected] ~]# vim /var/www/vhosts/example.com/info.php
<?php phpinfo(); ?>

And your done!