Setting up PHP-FPM and Nginx on Linode

Nginx is designed for very efficient serving of static files. This means that trying to use a dynamic scripting language such as PHP requires a bit of extra work compared to say an Apache installation. This post documents how I’ve set up my Linode with Nginx and PHP using the PHP-FPM extension.

Firstly it’s worth noting why I chose PHP-FPM over the much easier FastCGI route. To sum it up, FPM provides a much more stable platform and less overhead compared to FCGI route. Additionally, FPM support is set to be baked into the next versions of PHP so the additional build settings needed here should be obsolete soon hopefully.

Rather than detail all of the commands necessary to set up Nginx, MySQL and PHP, here’s a link to a bash script that does the whole job. This is set up as a StackScript on Linode, a very easy way to deploy a new server with this script automatically run.

Once that’s set-up and you’ve SSHd into your server (yes, you will need to use the command line, get over it) you can begin setting up your Nginx confs. The two main directories set to be used are /etc/nginx and /var/www.

Here is an example of a typical site conf file that lives in /etc/nginx/sites-enabled/hybridlogic.co.uk (Nginx is set to look for all confs in that directory, symlink from sites-available for easy disable/enable support).

server {
listen 80;
server_name hybridlogic.co.uk www.hybridlogic.co.uk;
access_log /var/log/nginx/hybridlogic.co.uk.access.log;
location / {
root /var/www/hybridlogic.co.uk/public_html;
index index.html index.php;
if (!-e $request_filename) {
rewrite ^.*$ /index.php last;
}
}
location ~ .php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/hybridlogic.co.uk/public_html$fastcgi_script_n$
include /etc/nginx/fastcgi_params;
}
}

This is a pretty typical example of an Nginx conf bar two sections:

Within the location is the equivalent of a htaccess mod_rewrite. All requests that do not correspond to a know file should be rewritten to use index.php. This lets me use pretty permalinks across l0ke.com.

The second point is the ~.php regex. This captures any request to a PHP file and passes it off to PHP with the fastcgi module in Nginx (this is different to using fastcgi in PHP itself. This was the bit that was causing me the most trouble until I realised that /usr/local/etc/php-fpm.conf was set to listen on the wrong IP. Edit the file to tell it to listen on your required IP/Port combo (for me I used listen=127.0.0.1:9000) and restart it via init.d. Set up a phpinfo.php file and test to make sure it’s going through.

You will now have an Nginx server capable of serving PHP pages. And best of all, this method can be used for Python, Ruby etc all within the same site.