PHP FPM Configuation
Last week I talked for a long while about using PHP FPM to speed up the site, but avoided offering up any of the configurations files. The support for FPM and Apache is still a bit thin on the ground — niginx seems to have quite a lot of support and questions out their on this topic already. As such, I'm not entirely sure if I'm doing this the most efficient way, so don't take this as good support advice.
The servers I'm using run Debian, which makes things easier. The packages
that I used were:
Note that mod_fcgi is non-free, and so may not show up on some configurations.
Consult your package manager's documentation on including the non-free package
lists. Alternatives exist to mod_fcgi, such as mod_fcgid. These may implement
other directives. PHP-FPM also comes with an inbuilt mod_php_fpmCitation Needed.
First, we configure PHP-FPM. I'm mainly using the default settings currently,
but one of the things I did do was to swap from listening for TCP connections
on a port to listening via a local socket.
listen = /var/php/blog.sock
Also, I configured the user that the processes run as, and the permissions on
user = www-blog
This configuration saves the overhead of dealing with TCP sockets, even over the loopback interface. It does, however, make the apache side of things slightly more complicated. I found that the default mod_php_fpm didn't have the documentation I needed to get it working in socket mode, so I had to sacrifice any performance enhancements that that has built into it. The core of the apache configuration required is2:
<VirtualHost blog.example.com:80> DocumentRoot /var/www/blog FastCGIExternalServer /var/www/blog/php5.fastcgi -socket /var/php/blog.sock Alias /php5.fastcgi /var/www/blog/php5.fastcgi Action blog-fastcgi /php5.fastcgi SetHandler blog-fastcgi AliasMatch ^.+ /var/www/blog/index.php/$0 </VirtualHost>
To explain what's going on, we're going to work from the bottom upwards. The AliasMatch directive is a another way of performing that very common pattern of using mod_rewrite to send all requests through a single script, which you will find used in all sorts of applications. It's slightly faster than using mod_rewrite3, but noticeably less flexible: I can't perform checks for whether the requested file actually exists. This is, however, something of a boon, as I don't need to think so much about security in terms of people directly requesting my internal files. Paired with the alias is a directive that all requests in this VirtualHost are handled by the blog-fastcgi action.
This action, much to my disappointment, takes three lines to set up. The Action directive, which names a particular script as an action, requires an external style URI — I believe this dates back to the days of http://example.com/cgi-bin/. This means we have to Alias a fake URI to our socket file. Furthermore, the Action directive isn't set up to take a socket directly; the FastCGIExternalServer directive allows us to bind a socket to a (potentially) non-existing file. Overall, this means our action points to a fake URI, which is aliased to a fake file, which Apache all interprets as a socket.
- 1 ↑ Citation Needed
- 2 ↑ Actually, it only looks like this is in terms of structure; I've changed the paths used so they match up with more common configurations
- 3 ↑ Which I don't have loaded on the blog server anyway.