Setting Up Nginx & PHP-FPM on Ubuntu 10.04

This is another wonderful setup that I’ve found myself using rather than the traditional Apache & mod_php setup.

What is Nginx?

Nginx (pronounced engine-x) is a fast, powerful, lightweight web server. I won’t go into the theory under-the-hood, but it’s focus is high concurrency with low memory usage. So while Apache is more robust in supporting many different features, nginx focuses on handling the important features very quickly. I still use Apache internally for our SVN & Trac web server. Heck, even at this time I’m using Apache to host this blog. However, Dating DNA, Clipish, CEVO, Alienware Arena, and some other high traffic sites/apis use nginx.

Ngnix, unlike Apache, doesn’t actually load PHP. Instead, it hands it off as a proxy to a “php handler” which acts like an Application Server. So nginx by itself won’t serve PHP files, but just static files.

What is PHP-FPM?

In the past, when working with something like Nginx or lighttpd, you would use spawn-fcgi to host your PHP application. However, spawn-fcgi had some major drawbacks and problems. So a guy named Andrei Nigmatulin created PHP-FPM, which stands for “PHP FastCGI Process Manager.” Since then, several others have contributed and ultimately it was include into the PHP core in version 5.3.3.

So from a high level look, on every PHP request Apache will load the entire installed PHP environment each time. This is for every request, and while it has been optimized as much as it can, that is a lot of overhead! With PHP-FPM, it will spin up a configurable amount of children. Each load the PHP environment and then will serve as many requests as it can without having to reload the environment. This saves on a lot of overhead!

Why use Nginx & PHP-FPM?

I should note, it is possible to configure/compile Apache in such a way that it can have similar performance capabilities. However, it takes a ton of work. Meanwhile, Nginx & PHP-FPM are very fast from the start, so I prefer just using them. You do lose some features, like .htaccess files won’t work so you’ll have to do that configuration in your virtual hosts.

How to Setup Nginx & PHP-FPM

Nginx

First off, lets setup Nginx.

sudo aptitude update
sudo apt-get install nginx
/etc/init.d/nginx start

Thats it! If you go to your server’s IP Address or Domain Name you should see a “Welcome to Nginx!”

PHP-FPM

Because PHP-FPM is only included by default in PHP 5.3.3 and later, and Ubuntu 10.04 LTS only has PHP 5.2.3, we have two options. Either we can install by source, or we can add another repository to install PHP-FPM. The latter is much, much easier, and there is a good PHP-FPM Repo for Ubuntu 10.04. To add it, you just run the following commands:

sudo aptitude install python-software-properties
sudo add-apt-repository ppa:brianmercer/php
sudo aptitude update

Now that we have the new repository, we can install PHP5:

sudo aptitude install php5-cli php5-common php5-mysql php5-suhosin php5-gd php5-dev
sudo aptitude install php5-fpm php5-cgi php-pear php5-memcache php-apc
/etc/init.d/php5-fpm restart

Excellent! Now, if you need to change some of PHP-FPM’s configurations, they are found in /etc/php5/fpm/. The file php5-fpm.conf configures how FPM will opporate, and the php.ini is the settings file that PHP will use while running in FPM.

A few settings I like to change in /etc/php5/fpm/php5-fpm.conf:

pm.max_children = 20

The php5-fpm.conf that comes is pretty well documented on the different settings. Once you make a change, make sure to restart php5-fpm.conf: /etc/init.d/php5-fpm restart

Configuring Nginx

Now, we have a few settings for Nginx. The configuration files are found in /etc/nginx/. First we’ll edit nginx.conf. Here are a few settings we’ll want to change:

user www-data;
worker_processes  4; # 1 to 4, I normally put this to the number of cores

error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
    multi_accept on; # uncomment this line
    use epoll; # Add This - We'll want Nginx to use epoll for event timing
}

http {
    include       /etc/nginx/mime.types;

    access_log  /var/log/nginx/access.log;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;
    tcp_nodelay        on;

    gzip  on;
    gzip_disable "MSIE [1-6].(?!.*SV1)";

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

Now, we need to add a VirtualHost! Nginx uses the same layout in Ubuntu as Apache, so we’ll add configurations for each site we want under /etc/nginx/sites-available/. So using vi, nano, or whichever editor you prefer, create a /etc/nginx/sites-available/www.example.com file:

# rewrite from example.com to www.example.com
server { 
	listen 80;
	server_name example.com;
	rewrite ^(.*) http://www.example.com$1 permanent;
}

server {
    listen   80;
    server_name www.example.com;
    access_log /var/log/nginx/www.example.com.access.log;
    error_log /var/log/nginx/www.example.com.error.log;

	client_max_body_size 4M;
	client_body_buffer_size 128k;
	expires 24h;
 
    location / {
        root   /var/www/example.com/;
        index index.html index.php;
		
        # if file exists return it right away
        if (-f $request_filename) {
                break;
        }

        if (-e $request_filename)
        {
                break;
        }

        # Useful rewrite for most frameworks, wordpress
        if (!-e $request_filename) {
                rewrite ^(.+)$ /index.php last;
                break;
        }

    }

    location /nginx_status {
      # copied from http://blog.kovyrin.net/2006/04/29/monitoring-nginx-with-rrdtool/
      stub_status on;
      access_log   off;
      allow 127.0.0.1;
      deny all;
    }

    location ~ .php$ {
        expires off;
        include /etc/nginx/fastcgi_params;
        fastcgi_pass  127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param  SCRIPT_FILENAME  /var/www/example.com/$fastcgi_script_name;
    }
}

Now, we need to create the symlink from sites-enabled to sites-available:

ln -s /etc/nginx/sites-available/www.example.com /etc/nginx/sites-enabled/www.example.com

Restart nginx with “/etc/init.d/nginx restart”. Go ahead and put a test.php file in your directory with a Hello World example, and see if it works. It should work, and you should be good to go.

12 thoughts on “Setting Up Nginx & PHP-FPM on Ubuntu 10.04

  1. Have you seen any issues running PHP 5.3 on Ubuntu from the repo you added? My company hesitates to add additional repos for security, but we also are thinking about migrating to Zend Framework 2.

    Like

  2. Huge shouts for the tutorial — it worked nice & smooth for me.

    Like

  3. Great tutorial! I had it up and running and it worked without a hitch.

    Thank you very much again!

    Like

  4. I believe you could replace those if clauses in the nginx config with tryfiles, as suggested at http://wiki.nginx.org/IfIsEvil.

    Like

  5. And by tryfiles I mean try_files. 🙂

    Like

  6. root@mf102 ~: add-apt-repository ppa:brianmercer/php
    Error: can’t find signing_key_fingerprint at https://launchpad.net/api/1.0/~brianmercer/+archive/php

    Anyone have a suggestion?

    Like

  7. @Israel

    It means the repo is gone. The new LTS of ubuntu is just about to release, and it will have PHP-FPM in it’s official repos. I decided to go ahead and upgrade early since it’s so close to release anyway. sudo do-release-upgrade -d

    Like

  8. i have an issue, i am around 23rd day about this matter, I installed nginx usiing this tuts. , Worked fine, Google listed my website, it is fast. But timthumb not working with nginx, i installed apache with fcgid with another vps, found working , with modern wordpress theme.

    while checking long time, i found that there is no php-fpm.conf file in my system, not generated automatically, the file is empty!

    just a php-fpm.conf can solve this?, if yes, kindly give me default php-fpm.conf file.

    Like

  9. i found great installation instruction in this blog, found worked for me, i didnt found any post problem related to it
    http://www.discusswire.com/nginx-php-fpm-mysql-auto-install-ubuntu/

    Like

  10. @garrett
    No it’s not

    @Israel
    I fixed it by running:

    $ sudo apt-key adv –keyserver keyserver.ubuntu.com –recv-keys 8D0DC64F
    $ sudo apt-get update

    Like

Leave a Reply to Gabriel Farrell Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this:
search previous next tag category expand menu location phone mail time cart zoom edit close