Configuring PHP-FPM For Ubuntu 14.04 & Apache 2.4

Posted: 28/06/15

There are numerous web pages telling you how to set up PHP-FPM but there's always room for one more. These notes refer to Ubuntu 14.04 which ships with PHP 5.5 and Apache 2.4

Starting with a completely fresh install of Ubuntu 14.04, here's how to configure everything:

First of all, we need to install the server software and configure Apache. You will need to enable the multiverse repository in /etc/apt/sources.list to that fastcgi is installed:

apt-get install mysql-server apache2-mpm-worker libapache2-mod-fastcgi php5-fpm php5 php5-mysql

Edit /etc/apache2/apache2.conf and add this directive:

<Directory /usr/lib/cgi-bin>
Require all granted
a2enmod actions
service apache2 reload

The php5-fpm init script is broken. When you attempt to reload php5-fpm, the master process will exit, leaving zombie child processes behind, or none at all. The fix is to remove or rename /etc/init.d/php5-fpm, and then to edit /etc/init/php5-fpm.conf and uncomment the line:

reload signal USR2

You can now use service php5-fpm reload to reload the configuration if you change it.

You now need to configure your virtual hosts to use PHP5-FPM to service requests. This requires a virtual host configuration and if you want to run PHP as a user other than www-data (which is kind of the point of the whole exercise) a PHP5-FPM configuration. Here are some sample configuration files:

<VirtualHost *:80>
        <IfModule mod_fastcgi.c>
                AddHandler user-fcgi .php
                Action user-fcgi /user-fcgi virtual
                Alias /user-fcgi /usr/lib/cgi-bin/user-fcgi
                FastCgiExternalServer /usr/lib/cgi-bin/user-fcgi -socket
/var/run/user-fpm.sock -pass-header Authorization -idle-timeout 3600
        DocumentRoot /home/user/www
        ServerAdmin postmaster@localhost
        <Directory /home/user/www>
                Require all granted
                AllowOverride All

Points to note:

1) /usr/lib/cgi-bin has to exist, and has to be accessible to Apache. That's why the directive was added to apache2.conf

2) /usr/lib/cgi-bin/user-fcgi must not exist

3) If you need to have several users, they must use unique handlers. You cannot declare user-fcgi in any other virtual host or Apache will throw an error and won't start. You can use anything you like as long as it does not exist in /usr/lib/cgi-bin/ and is unique.

4) Idle timeout needs to be a lot longer than PHP's max-execution-time, in this case one hour otherwise attempts to override will be futile.

Here is an example PHP5-FPM pool configuration which you should place in /etc/php5/fpm/pool.d/user.conf, etc:

  1. [user]
  2. user = user
  3. group = user
  4. listen = /var/run/user-fpm.sock
  5. listen.owner = www-data
  6. = www-data
  7. pm = dynamic
  8. pm.max_children = 10
  9. pm.start_servers = 4
  10. pm.min_spare_servers = 2
  11. pm.max_spare_servers = 10
  12. chdir = /
  13. php_admin_value[memory_limit] = 128M
  14. php_value[max_execution_time] = 30
  15. php_admin_value[open_basedir] = /home/user/:/tmp:/usr/share/php/
  16. php_value[error_reporting] = E_ALL & ~E_NOTICE & ~E_DEPRECATED
  17. php_admin_flag[log_errors] = on

Points to note:

  • The listen value (4) must match that specified in the virtual host
  • Default PHP configuration is taken from /etc/php5/fpm/php.ini, which can be overridden by php_admin/php_flag settings in the file(s) in pool.d
  • php_admin_value specifies a PHP configuration setting that cannot be changed at run time. Similarly the php_admin_flag sepcifies a PHP boolean setting that also cannot be altered at run time.
  • php_value/php_flag are similar, but can be overridden in your PHP code.