February 13, 2014

Set up Apache (2.4) with php-fpm on Ubuntu 13.10

Recently I was trying to help a friend get Apache working with php-fpm on Ubuntu 13.10, I’m generally more of a CentOS guy and have recently switched to nginx from apache, so this was slightly unfamiliar territory for me.  The fact that the default php-fpm install on ubuntu uses sockets but mod_proxy_fcgi doesn’t support sockets yet,  combined with some differences between apache 2.2 and apache 2.4 made this a little tricky, so I figured that I would lay it out for anyone else looking for answers.

Step 1 – Install apache, php and enable mod_proxy_fcgi

$ sudo apt-get install apt-get install apache2 php5-fpm php5
$ sudo a2enmod proxy_fcgi

 Step 2 – Edit your php-fpm config to use a localhost port rather than a socket

In your favourite text editor (vim) open up /etc/php5/fpm/pool.d/www.conf

and change

listen = /var/run/php5-fpm.sock

to

 listen = 127.0.0.1:9000

and then restart php5-fpm

$ sudo service restart php5-fpm

 

Step 3 – Setup your apache virtual host file

Lets start with the default config, then edit it to match our needs. Navigate to the apache sites-available directory and copy the default config to your new config, we’ll call it yoursite.com.conf

$ sudo cd /etc/apache2/sites-available
$ sudo cp 000-default.conf yoursite.com.conf

You need to set the ServerName, DocumentRoot and add the ProxyPassMatch line along with the Directory stanza, making sure that your DocumentRoot is used for the values in ProxyPassMatch and the Directory stanza.  I like to set the document root to a folder named after the site of the virtual host inside /var/www so for yoursite.com it should look something like this

<VirtualHost *:80>
        # The ServerName directive sets the request scheme, hostname and port that
        # the server uses to identify itself. This is used when creating
        # redirection URLs. In the context of virtual hosts, the ServerName
        # specifies what hostname must appear in the request's Host: header to
        # match this virtual host. For the default virtual host (this file) this
        # value is not decisive as it is used as a last resort host regardless.
        # However, you must set it for any further virtual host explicitly.
        ServerName yoursite.com

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/yoursite.com

        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf

        ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/yoursite.com/$1

        <Directory "/var/www/yoursite.com">
                Order allow,deny
                Allow from all
                AllowOverride FileInfo All
                # New directive needed in Apache 2.4.3:
                Require all granted
        </Directory>

</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

 

Step 4 – Setup a test page

I generally like to test new php setups with a simple phpinfo script, ensure the DocumentRoot directory you previously defined exists and create it if it doesn’t, then add a phpinfo index.php file

$ sudo mkdir -p /var/www/yoursite.com
$ sudo echo "<?php phpinfo(); ?>" > /var/www/yoursite.com/index.php

 

Step 5 – Restart apache and test it out

$ sudo service apache2 restart

Point your web browser to the site and you should now see a php information page!

Caveats

It appears that the proxypass doesn’t work well with apache aliases, like the ones that you get from wordpress and phpmyadmin if you install them with apt. However, if you install them “normally” by putting them in a directory on your vhost, or in the root of your vhost itself they should work assuming you have all the other required php extensions installed.

EDIT: To use Aliased sites with php-fpm you just need more proxypass rules for them, and also leave the Alias line in the config for the site (ie wordpress/phpmyadmin)

This setup works for phpmyadmin installed with apt-get install phpmyadmin. Make sure they come BEFORE the default ProxyPassMatch line in the vhost config file.  You can also move all of the proxypass lines to something like /etc/apache2/conf-available/php-fpm.conf then do “a2enconf php-fpm” to enable it.

ProxyPassMatch ^/phpmyadmin/(.*\.php)$ fcgi://127.0.0.1:9000/usr/share/phpmyadmin/$1
ProxyPassMatch ^/phpmyadmin(.*/)$ fcgi://127.0.0.1:9000/usr/share/phpmyadmin$1index.php

This is also a very simple setup, you can refer to other articles for information on how to best optimize php-fpm pools and apache performance, but this should get you a bare minimum working config suitable for a development environment or small blog.