I managed to get this working without too many problems by following the directions at Koen Reiniers' dev blog. I followed the directions almost exactly, and with one exception, noted in the blog post comments, it worked perfectly. You will need mod_fastcgi, as well as several other modules. This recipe will enable you to set up multiple vhosts, each of which uses an independent php7 fpm configuration. Note that unless phpinfo() is showing a server API of "FPM/FastCGI" then you've missed the mark. This is the acid test that you have the stack working. As a check, I also executed "<?php touch('/tmp/fpmtest');" to check that processes started for my vhost were executing as the specified user/group (they were).
This recipe is copied, with a few modifications, from Koen's blog, and credit is due to him for his clear and effective directions.
With the possible exception of the security-related stanzas in it, you do not want to enable the Apache conf for php7.0-fpm if you use this recipe. The only code that needs to be globally executed is:
<Directory "/usr/lib/cgi-bin">
Require all granted
</Directory>
If your Apache2 configuration enables mod_cgi.c then this has probably already been taken care of in the default conf file for the module. Otherwise, if this module (or mod_cgid.c) isn't already enabled, this can be added to any conf file which is executed at Apache2 startup, although, depending on your server environment, it might be more secure to add it only to each <VirtualHost> for which PHP-FPM is enabled. Security-related code from php7.0-fpm.conf could also be copied to the same location, or enabled globally.
This guide assumes you have PHP 7.0.* running, as well as Apache (with virtual hosts), on a Ubuntu server. Also, please do not try this on a production environment without having proper backups in place.
First make sure php7.0-fpm is installed on your system:
$ sudo apt-get install php7.0-fpm
After it has been installed, start the service if it hasn’t automatically, and verify that it's running:
$ sudo service php7.0-fpm start && ps aux | grep php-fpm
To use PHP-FPM for each and every one of your virtual hosts you will have to split it into multiple resource pools, one for every separate <VirtualHost> user, which means that if you have multiple hosts assigned to one user you will only have to create one resource pool for that user.
The default location for the pool configuration for PHP-FPM is:
/etc/php/7.0/fpm/pool.d/
To create a new configuration for one of your users, simply create a new .conf file. I used the user’s username as the name of the config file:
$ sudo vim /etc/php/7.0/fpm/pool.d/username.conf
And use this as your configuration (replace "username" with the actual name of your user):
[username]
user = username
group = username
listen = /run/php/php7.0-fpm.username.sock
listen.owner = username
listen.group = username
listen.mode = 0666
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
The first seven lines are the most important. Make sure that they are the same as the Apache virtualhost user. The last five lines are the default settings for the process manager. Leave them as is for the sake of simplicity, but you can change them to your liking. You can read more about these settings in the default config file located at:
/etc/php/7.0/fpm/pool.d/www.conf
The only thing remaining is telling Apache to use PHP-FPM instead of mod_php. First, make sure you have both mod_actions and mod_fastcgi enabled:
$ sudo a2enmod actions fastcgi
$ sudo service apache2 restart
Add the PHP-FPM fastcgi handler to Apache. You will have to do this for every user that you want to be able to user PHP-FPM. Edit the per-vhost file for username, typically at:
/etc/apache2/sites-available/username.conf
Add the following at the top:
<IfModule mod_fastcgi.c>
AddHandler php7-fcgi-username .php
Action php7-fcgi-username /php7-fcgi-username
Alias /php7-fcgi-username /usr/lib/cgi-bin/php7-fcgi-username
FastCgiExternalServer /usr/lib/cgi-bin/php7-fcgi-username -socket /run/php/php7.0-fpm.username.sock -pass-header Authorization
</IfModule>
Again, replace "username" with the actual name of the vhost’s user.
You must tell your vhost to actually use it for .php files, so in the same file, but in the <VirtualHost> directive, add the following lines:
<IfModule mod_fastcgi.c>
<FilesMatch ".+\.ph(p[3457]?|t|tml)$">
SetHandler php7-fcgi-username
</FilesMatch>
</IfModule>
Replace “username” with the name of the actual vhost user again and save the file. It's very important that the SetHandler directive be wrppped with a subset of of the Apache conditional filesystem container tags, <Location>, <LocationMatch>, <Files> or <FilesMatch>. Ommitting this will cause SetHandler to be ignored. The <Directory> tag apparently doesn't cut it.
If you want to take advantage of PHP-FPM's "status" and "ping" capabilities, and have them turned on in your per-vhost pool file in the /etc/php/7.0/fpm/pool.d directory (see /etc/php/7.0/fpm/pool.d/www.conf for details) you'll need to make two additional modifications to your Apache2 setup. The Action directive at the top of the per-vhost .conf file must terminate with "virtual", thus:
Action php7-fcgi-username /php7-fcgi-username virtual
Additionally, your SetHandler wrapper must specify a regular expression which includes these virtual files. I use the following:
<LocationMatch ".+\.ph(p[3457]?|t|tml)|/(ping|status)$">
SetHandler ....
</LocationMatch>
Now all that is left is to let Apache reload its config files:
$ sudo service apache2 reload
To see if your changes have taken effect, create a phpinfo.php file in your website’s public directory and visit it in your browser:
<?php phpinfo();
The Server API shown near the top of the page should show "FPM/FastCGI".
To complete the process, you should repeat the steps for each of your virtual hosts. When you are entirely sure mod_php is not being used anymore you can disable it through:
$ sudo a2dismod php7.0
Until you’ve done this, Apache will still include a PHP process for every request, meaning the memory usage will stay the same and possibly be even higher.