Guide to combining Apache virtual hosts and PHP7 FPM

So, I recently decided to abandon my old directadmin server and migrate to a fresh Ubuntu server. The main reason for this was the long-awaited release of PHP 7.0.0. This meant I had a chance to start all over and create the fastest possible setup for my server.

This guide assumes you have PHP 7.0.* running on your server 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.

At first, I decided to just go with Apache using mod_php, since it was the easiest to setup.The downside of this is the increased memory usage of Apache, since every instance of it also includes a PHP instance. Even for static resources.

This is where PHP-FPM comes into play. PHP-FPM runs as a separate process from Apache and only get instantiated when necessary. This decreases the memory usage of each Apache instance, and thus, decreasing the load on the server.

On to the actual guide. First we’re going to make sure php7.0-fpm is installed on your system:

$ sudo apt-get install php7.0-fpm

After it has been installed, you have to start the service if it hasn’t automatically:

$ sudo service php7.0-fpm start

That’s it, PHP-FPM is now running on your system. Apache does not know about it yet though and is still using mod_php.

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. Meaning 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 vi /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

    pm = dynamic
    pm.max_children = 5
    pm.start_servers = 2
    pm.min_spare_servers = 1
    pm.max_spare_servers = 3

The first six 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. I decided to leave them as is for the sake of simplicity, but you can change them to your likings. You can read more about these settings in the default config file located at

/etc/php/7.0/fpm/pool.d/www.conf

Now reload PHP-FPM to make sure your configuration is loaded:

$ sudo service php7.0-fpm reload

Now that we have PHP-FPM set up for one of your users, 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

And restart Apache to have the changes take effect:

$ sudo service apache2 restart

Now it’s time to 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. I used a macro for this myself, but the easiest way is to edit your vhosts config, typically located at:

/etc/apache2/sites-available/username.conf

Add the following at the top:



    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

    
    Require all granted
    
    

Again, replace “username” with the actual name of the vhost’s user.

Now that we’ve added the PHP-FPM fastcgi handler, all that is left is to tell your vhost to actually use it for .php files. So in the same file, but in the directive, add the following lines:


    
        SetHandler php7-fcgi-username
    

Replace “username” with the name of the actual vhost user again and save the file. Now all that is left is to let Apache reload its config files:

$ sudo service apache2 reload

To see if your changes had any effect, create a phpinfo.php file in your website’s public directory and visit it in your browser:


Look for "Server API". If everything went well, it should say"FPM/FastCGI". Congrats, you are now running PHP-FPM on this virtual host.

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.

Disclaimer: I've only recently started deploying my own servers, so it is entirely possible there are easier and/or better ways to achieve the above. I am open for any suggestions, so please feel free to leave a comment or email me.