PHP-FPM sockets with Apache 2.4 and mod_proxy_fcgi on Ubuntu 14.04 LTS

If you don't feel like reading skip to the instructions.

The status quo

Apache running mod_php has been the status quo for years, this embeds a PHP interpreter in each Apache process, sharing the interpreter between many virtual hosts, the major problem is a single virtual host can bring it all crashing down!

If you have ever been bitten by this you likely locked down your php.ini and Apache configs (and you always should). You have possibly played around with suphp, mod_suexec or mod_fastcgi, but this always seems messy!

Why not use nginx?

Using nginx and FastCGI is a popular alternative, getting this up and running is not always easy.

Many apps have been built around Apache and the modules it provides like .htaccess files, mod_rewrite or multiviews, without these the app may not work correctly, if at all.

You may need to adjust application code or nginx config files to get things working, this becomes a problem when you have thousands of virtual hosts.

If what I've just mentioned does not affect you, stop reading and go use nginx.

Apache 2.4 and mod_proxy_fcgi

Apache 2.4 and mod_proxy_fcgi has worked nicely with PHP-FPM using TCP/IP sockets for some time with just the stock Apache httpd and php.net releases.

I'm pleased to see a couple of recent improvements:

I personally don't like things listening on the network (local or not) unless it needs to, unix socket support was a big win for me.

Enough flapping, how do we set this up? (Ubuntu 14.04 LTS)

Okay okay… below we are going to setup:

You need Apache 2.4.10 or newer, currently available from a PPA by Ondřej Surý's.

The instructions below are all bundled together so you can copy them into your text editor and replace occurrences of example and example.com with your own settings then paste into a terminal window. But I suggest you do it one step at a time to see what's going on.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# Install packages
sudo add-apt-repository -y ppa:ondrej/apache2
sudo apt-get update
sudo apt-get -y install apache2 php5-fpm

# Create directory to contain multiple apache vhosts
sudo mkdir /srv/vhost
chmod 0751 /srv/vhost
chown www-data:www-data /srv/vhost

# Create user (example) and group (example) that the PHP-FPM pool will use
sudo groupadd example
sudo useradd -m -g example -d /srv/vhost/example -c 'vhost runtime' example
sudo mkdir /srv/vhost/example/public_html
sudo chown example:example /srv/vhost/example/public_html

# Create PHP-FPM pool configuration (example)
sudo bash -c 'cat > /etc/php5/fpm/pool.d/example.conf <<EOF
[example]
chdir = /

user = example
group = example

listen = /var/run/php5-fpm.sock.example
listen.owner = www-data
listen.group = www-data

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

EOF'

# Allow files to be served from our virtual hosts `public_html` directory
sudo bash -c 'cat > /etc/apache2/conf-available/vhost-permissions.conf <<EOF
<Directory "/srv/vhost/*/public_html">
  Options +SymLinksIfOwnerMatch
  AllowOverride AuthConfig FileInfo Indexes Limit Options=Indexes,MultiViews
  Require all granted
</Directory>

EOF'

# Create Apache virtual host configuration
sudo bash -c 'cat > /etc/apache2/sites-available/example.conf <<EOF
<VirtualHost *:80>
  ServerName example.com
  DocumentRoot /srv/vhost/example/public_html

  <FilesMatch \.php$>
    SetHandler "proxy:unix:/var/run/php5-fpm.sock.example|fcgi://localhost"
  </FilesMatch>
</VirtualHost>

EOF'

# Enable Apache modules, config files and virtual hosts
sudo a2enmod -m proxy_fcgi
sudo a2enconf -m vhost-permissions.conf
sudo a2ensite -m example

# **n.b.** If your testing using an IP address (and not a domain) you need
#          to disable the default apache virtual host, or better yet replace
#          it with your own.
sudo rm /etc/apache2/sites-enabled/000-default.conf

# Restart services to pickup config changes
sudo service php5-fpm restart
sudo service apache2 restart

# Drop in a phpinfo() file to test it works
sudo bash -c 'echo "<?php phpinfo(); ?>" > /srv/vhost/example/public_html/index.php'
sudo chown example:example /srv/vhost/example/public_html/index.php

If everything restarted without error you are ready to roll and test it out!

Fin.

Luke Antins

About Luke Antins

Hello, I'm Luke Antins, a freelance software engineer & consultant based in the North West of England. For over 15 years I have been crafting software and using technology to solve problems for business.

I thrive on solving difficult problems, especially the ones no one else dares to touch! I have a passion to deliver both quality and valuable solutions to help your business keep up with a world thats ever-changing.

comments powered by Disqus