Setting Up Lighttpd with PHP-FPM

PHP-FPM can provide an alternative to spawn-fcgi when setting up Lighttpd with PHP. It has several advantages over using spawn-fcgi among them:

  • It can dynamically scale and spawn new processes as needed.
  • Gracefully respawn PHP processes after configuration change.
  • Comes with init.d script so no need write your own.
  • Ability to log slow PHP script execution (similar to MySQL’s slow query log).

Installation

PHP-FPM is available from the Ubuntu (since 12.04) and Debian’s repositories, so all you need to do is:

$ sudo apt-get install php5-fpm

Configuration

PHP-FPM works with process pools. Each pool spawns processes independently and have different configurations. This can be useful to separate the PHP process of each user or major site on the server. PHP-FPM comes with a default pool configuration in /etc/php5/fpm/pool.d/www.conf. To create new pools, simply copy the default pool configuration and edit it. At least you will need to set the following:

  • Pool name – [www]. I name mine according to the user which the pool serves.
  • user – I set the user to the appropriate user, and leave group as www-data.
  • listen = /var/run/php.$pool.sock – Unix sockets have lower overhead than tcp sockets, so if both Lighttpd and PHP run on the same server they are preferable. $pool will be expanded to your pool name. Also, it is more secure to create the sockets in a directory not writable globally (such as /tmp/) so /var/run is a good choice.
  • listen.owner should match the PHP user, while listen.group should match the group Lighttpd runs in, so both have access to the socket.

If you copied www.conf to create new configuration, you will need to rename it to something like www.conf.default in order to disable it.

In the Lighttpd configuration you need to add the following to each vhost that uses PHP:

fastcgi.server    = ( ".php" => 
        ((
                "disable-time" => 0,
                "socket" => "/var/run/php.pool.sock",
        ))
)

Where pool in the socket configuration is replaced by the matching pool name in the PHP-FPM configuration. Overriding disable-time and setting it to 0, is suitable in the case you have only one PHP backend and it’s local. In this scenario, attempting to connect to the backend is cheap, and if it gets disabled no requests will get through any way.

Useful Files

  • /etc/php5/fpm/pool.d – The PHP-FPM pool configuration directory.
  • /var/log/php5-fpm.log – The PHP-FPM error log. It will display error and warning notifying you when pm.max_children has been reached, when processes die unexpectedly, etc.

Question Marks Instead of Non-ASCII Chars when using Gettext in PHP

Yesterday I’ve ported a PHP website to use Gettext for localizations (l10n). After reading through the Gettext documentation and going through the documentation in the PHP site, I’ve manged to get everything working (almost). I had one problem, all the non-ASCII characters (accented Latin chars, Japanese and Chinese) where displayed as question marks (?) instead of the correct form. This happened despite me using UTF-8 encoded files.

While some people (e.g. this one) suggested that it’s not possible to use non-ASCII characters when using a UTF-8 encoded message files, there is a solution and it’s quiet simple one. All you have to do is to call bind_textdomain_codset and pass it UTF-8 as charset.