Installing PHP 5.3, Nginx And PHP-fpm On Ubuntu/Debian

Want to support HowtoForge? Become a subscriber!
 
Submitted by Sypher (Contact Author) (Forums) on Mon, 2010-02-08 17:23. :: Debian | Ubuntu | nginx | PHP

Installing PHP 5.3, Nginx And PHP-fpm On Ubuntu/Debian

Version 1.1
Follow me on Twitter

Since Apache is most of the time a memory hungy process, people started to look for different ways to host their website. Apache is clearly not the only webserver available. A few good examples are lighttpd and nginx. In this tutorial I will show you how to install it on your Ubuntu server. This tutorial also applies to Debian, though. There is only a very small difference.

Ready? Let's begin shall we.

 

Step 0 - Preliminary Notes

In order to complete this tutorial, I assume you have installed a base system of Debian or Ubuntu. How this can be done, can be read in different tutorials. This tutorial only focusses on getting nginx+php running without much hassle.

 

Step 1 - Nginx

Installing nginx is the first step we have to do. This can be easily done by downloading it from the repository.

sudo apt-get install nginx

The default vhost has to be changed in order to work properly.

sudo vim /etc/nginx/sites-available/default

A nice starting point for your config is:

server {
    listen   80;
    server_name  localhost;
    access_log  /var/log/nginx/localhost.access.log;

## Default location
    location / {
        root   /var/www;
        index  index.php;
    }

## Images and static content is treated different
    location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|xml)$ {
      access_log        off;
      expires           30d;
      root /var/www;
    }

## Parse all .php file in the /var/www directory
    location ~ .php$ {
        fastcgi_split_path_info ^(.+\.php)(.*)$;
        fastcgi_pass   backend;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /var/www$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_param  QUERY_STRING     $query_string;
        fastcgi_param  REQUEST_METHOD   $request_method;
        fastcgi_param  CONTENT_TYPE     $content_type;
        fastcgi_param  CONTENT_LENGTH   $content_length;
        fastcgi_intercept_errors        on;
        fastcgi_ignore_client_abort     off;
        fastcgi_connect_timeout 60;
        fastcgi_send_timeout 180;
        fastcgi_read_timeout 180;
        fastcgi_buffer_size 128k;
        fastcgi_buffers 4 256k;
        fastcgi_busy_buffers_size 256k;
        fastcgi_temp_file_write_size 256k;
    }

## Disable viewing .htaccess & .htpassword
    location ~ /\.ht {
        deny  all;
    }
}
upstream backend {
server 127.0.0.1:9000;
}
 

Ok, we're done here. Now we'll install the needed files for PHP.

 

Step 2 - Installing PHP

Many sites rely on PHP for providing them dynamic content, whether this is a wiki, forum software, weblog or something entirely different.

If you are running Ubuntu, we first have to resolve two dependencies required for the dotdeb packages. If you are running the amd64 version, you should replace i386 with amd64.

For Debian you won't have to do this!

cd /tmp

wget http://us.archive.ubuntu.com/ubuntu/pool/main/k/krb5/libkrb53_1.6.dfsg.4~beta1-5ubuntu2_i386.deb

wget http://us.archive.ubuntu.com/ubuntu/pool/main/i/icu/libicu38_3.8-6ubuntu0.2_i386.deb

sudo dpkg -i *.deb

Again, this is only required if you're on Ubuntu.

The rest of the tutorial applies to both Ubuntu & Debian.

We'll have to add the dotdeb repository to the APT sources, so we can use their packaged PHP 5.3 and php-fpm:

sudo echo "deb http://php53.dotdeb.org stable all" >> /etc/apt/sources.list

Update apt:

sudo apt-get update

The resulting text should include dotdeb.

Now we'll install PHP (part 1):

sudo apt-get install php5-cli php5-common php5-suhosin

We have to install the cli before the rest, because this will cause problems later on.

sudo apt-get install php5-fpm php5-cgi

If you are planning to use a database or require specific modules (mcrypt, ldap, snmp etc) you can install them as well.

Ok, so now we have nginx and PHP.

One minor remark: If you are using "php short tags" (<?) you should enable them in your php.ini files (for both fpm and cli). If you do not change this, you will see your code in plain text!

 

Step 3 - Finalizing

Restart nginx in order to catch up with the config changes we made earlier.

sudo /etc/init.d/nginx restart

The restart should have gone without any problems.

After installing php5-fpm, it should have been started. If you did change your php.ini files, you have to restart php5-fpm.

sudo /etc/init.d/php5-fpm restart

All right. They should now both be running.

 

Step 4 - Testing

In order to test if the execution of PHP is working, create an index.php file in /var/www with the following content:

<?php phpinfo(); ?>

Visit your webserver and you should be able to see the generated phpinfo. If not, something went wrong.

 

Step 5 - Troubleshooting & Final notes

If  you did not see the phpinfo, there might be something wrong. In order to track down what went wrong, you can check the nginx error log:

sudo tail /var/log/nginx/error.log

Remember, if you did change your php.ini you have to restart php5-fpm. Restarting nginx isn't' necessary.

In my example config I've enabled the fastcgi error interception. If a serious error occurs (for instance a "cannot redeclare class xyz"), nginx can catch this page and show a "nice" error page that something went wrong. This way, there is less information given out in case something is going seriously wrong.

If you do not like this, you can turn it off.

If php5-fpm is not running, your PHP files cannot be parsed and nginx will show the user an error page.

Well, I guess we're done and you are now able to serve PHP with your new nginx based webserver. Nginx is pretty nice and you can configure a lot. If you need rewrites, be aware that nginx does not work with .htaccess files. You will need to change your vhost settings in order for the rewrites to work.


Please do not use the comment function to ask for help! If you need help, please use our forum.
Comments will be published after administrator approval.
Submitted by heronote (not registered) on Thu, 2011-10-13 02:43.
Free nginx eBook: http://www.heronote.com/files/nginx.htm
Submitted by Anonymous (not registered) on Thu, 2011-09-01 04:43.

You can replace the dependencies and sources.list editing with:
sudo add-apt-repository ppa:nginx/php5

Submitted by Wladimir Tavares (not registered) on Sat, 2011-08-27 13:11.

First of all, my thanks for this great website of yours. It has saved me days!

Please update your article.

 I was having this error message

Reading package lists... Done

W: GPG error: http://php53.dotdeb.org stable Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY E9C74FEEA2098A6E

According to http://www.dotdeb.org/2010/07/11/dotdeb-packages-are-now-signed/ their packages are signed. 
You need to to import dotdeb repository keys before the update
sudo apt-get update

Please add this two commands before the update.

gpg --keyserver keys.gnupg.net --recv-key 89DF5277

gpg -a --export 89DF5277 | sudo apt-key add -

 

Submitted by Kuba (not registered) on Thu, 2011-05-05 22:31.

Since Ubuntu 11.04 is bundled with PHP 5.3, installation is as simple as:

sudo apt-get install php5-fpm php5-cli php5-common

Submitted by Ellis Grouse (not registered) on Wed, 2011-04-06 21:39.

Love it - brilliant tutorial, got me online within minutes.

Considering the never-ending messing around I've had to do with nginx + php in the past, this is pure quality.

 Running latest Debian, latest PHP.

 

Submitted by Longodongo Peep... (not registered) on Mon, 2011-01-31 16:01.

Why are you overwriting fastcgi_param variables that have been included already?

When I see somebody doing things like this, I get the idea that the guy not really wrote the config line by line for himself - maybe he is not even knwoing exactly what he is doing! And all you rabbits are just blindly running into his direction? 

Submitted by Anonymous (not registered) on Wed, 2011-02-02 15:57.

I agree.  I've been looking at various nginx configurations and any time I see the "big ol' list of fastcgi_... options" or someone using 'if (-e ...)' instead of 'try_files', I run away.  Far, far away.  I'm quite convinced that there isn't a single person publishing tutorials like this on nginx that actually knows how to create a functional configuration file.  The problem seems to stem from Igor's (the author of nginx) inability to follow his own rules for the default, shipping configuration combined with the lack of centralized documentation that is easy to follow.  There is a Wiki that is semi-useful but even the examples within the Wiki break the rules more often than not.

When I say "break the rules", I mean violations of the official "if is evil" and "common pitfalls" documentation in the nginx Wiki.

From what I've gathered, nginx is faster for two reasons:

  1. The default out-of-the-box installation isn't laden down with unnecessary modules.  Supposedly, Apache compiled for mpm-worker mode (default is mpm-prefork) can be configured to be just as fast as nginx when the unnecessary modules are stripped out.
  2. nginx doesn't touch the filesystem unless it is told to.  It is first a lightweight proxy server and second a web server while Apache is the reverse.  nginx was designed to be, in essence, a load balancer.  The approach is interesting because not touching the file system has the advantage of not having the physical files on the same box as the server.  'try_files', in this context, appears to have been introduced because people are using nginx as a web server.  But, more importantly though, this security vulnerability is in most nginx + PHP configurations found throughout the Internet.  When you think about it, there is no good way to fix it either except on a case-by-case basis using extra checks in each and every virtual host that allows PHP scripts to run or to run nginx as a lightweight proxy server that passes requests onto Apache - which has its own difficulties (e.g. dealing with remote IP addresses in PHP).

The lack of .htaccess support means that making changes requires modifying the configuration file, which means nginx probably won't work well in a hosting environment where people are used to having .htaccess available at the subdirectory level.

And the unfixable PHP security vulnerability is a head-spinner.

In essence, nginx is a special-purpose server that is only practical when there are extremely large loads to be handled for a single domain combined with a really intelligent system administrator.

Submitted by Anonymous (not registered) on Wed, 2012-10-31 16:12.
"I'm quite convinced that there isn't a single person publishing tutorials like this on nginx that actually knows how to create a functional configuration file."

Totally agree but...

"In essence, nginx is a special-purpose server that is only practical when there are extremely large loads to be handled for a single domain combined with a really intelligent system administrator." 

Not even close. Nginx is hugely useful for quick reverse proxies even on tiny servers with several low volume sites.

Submitted by Cristian Vrabie (not registered) on Tue, 2011-01-04 16:47.

I had some problems with links and redirects (in phpbb) when I used a setup similar to what you're describing. I had more success by using the root parameter instead of concatenating the path into SCRIPT_FILENAME. The config that works the best for me is something like:

location ~* \.php{
   root /var/www-bfg;
   fastcgi_pass 127.0.0.1:9000; 
   #other parameters here
 }
Submitted by Initcron (not registered) on Wed, 2010-09-22 13:31.
I have automated  nginx + php5 + php5-fpm setup  on ubuntu 10.4 lucid  with my scripted install. It is available freely under GNU GPL 3.0  at   http://www.initcron.org/how-tos/autoinstall-nginx-web-server-with-php-on-ubuntu-10-4-lucid  
This takes care of most of the steps above.
Submitted by Anonymous (not registered) on Wed, 2010-05-19 04:45.
    To those working with Ubuntu 10.04 (Lucid Lynx), you must ignore the deb item in the sources.list in the above tutorial, and skip all the steps relating to manually installing packages with dpkg. I tried this earlier and got it working, but I had to dkpg --ignore-depends , which resulted in a stubbornly broken apt-get with unmet dependencies. Here is the fix:
Instead put these in sources.list
  • deb http://ppa.launchpad.net/brianmercer/php/ubuntu lucid main
  • deb-src http://ppa.launchpad.net/brianmercer/php/ubuntu lucid main
And at then run this:
  • sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8D0DC64F
  • sudo aptitude update
  • sudo aptitude install php5-fpm
  • Submitted by Macario (not registered) on Mon, 2010-05-17 11:56.
    Hi I followed the tutorial using Ubuntu 10.04. First issue I encountered is that Lucid's php5-common package installs an Ubuntu specific version and php-fmp depends on other version, I solved it using dpkg to install php5-fmp ignoring dependencies. Now the problem is when i point the browser to index.php i get this message: No input file specified. Thanks for this tutorial Macario
    Submitted by Matt (not registered) on Tue, 2010-05-18 18:45.

    Regarding Lucid:  to give precedence to the php5 dotdeb packages, the following worked for me...

     sudo apt-get install php5-common=5.3.2-0.dotdeb.2 php5-cli=5.3.2-0.dotdeb.2 php5-suhosin=5.3.2-0.dotdeb.2

     Obviously, check the versions first: http://php53.dotdeb.org/dists/stable/php5/binary-i386/

     

    Submitted by Anonymous (not registered) on Tue, 2010-04-27 23:43.

    i get this

    pizza:/etc/nginx/sites-available# /etc/init.d/nginx restart

    Restarting nginx: 2010/04/27 18:40:56 [emerg] 2820#0: unknown directive "fastcgi_split_path_info" in /etc/nginx/sites-enabled/default:21

     

    im using exactly the same configuration file (default) as you.

    Submitted by fauzievolute (not registered) on Mon, 2010-05-10 23:03.

    Me too. I have same problem. How to fix it?

     Please...

    Submitted by Anonymous (not registered) on Tue, 2010-05-25 17:37.

    fastcgi_split_path_info was introduced around nginx version 0.7.31.  Are you using an older version?  You may need to comment that out or upgrade nginx if you need that functionality.

    Submitted by Daniel (not registered) on Sat, 2010-02-27 20:07.

    I wonder which Ubuntu version you based this on, as php5-fpm is not yet available with current Ubuntu. (9.10)

     Good totorial anyhow, given you have the package available.

    Submitted by Tyrael (not registered) on Tue, 2010-03-16 15:37.

    debian lenny with dotdeb.org php53 repository.

     Tyrael

    Submitted by Sypher (registered user) on Fri, 2010-03-26 20:01.

    You can use either Ubuntu or Debian, as long as you're able to use the DotDeb repository.

    Hopefully php-fpm will become a package in the main repositories, in that case you could use those. Until then, dotdeb will do.

    Submitted by Anonymous (not registered) on Sun, 2010-04-11 04:29.

    offtopic: Its nice to see people using something different from apache... i used to use it... i remember the first thing i did after installing it.. was removing *every* unnecesary module (I dont know why, its very common to have many shit that you probably will never use... and in fact, just gives  security holes to any newcomer...) *greets*

    Submitted by Anonymous (not registered) on Mon, 2010-03-15 15:05.

    Within [/etc/nginx/sites-enabled/default]

    I had to change:

    fastcgi_pass backend;

    to

    fastcgi_pass 127.0.0.1:9000;

     Not sure why, but it worked after that.

    Submitted by thaicla (not registered) on Thu, 2010-06-24 04:59.

    Can use in debian lenny?

    I can't use php on nginx.

    Thanks,

    thaicla

    Submitted by Sypher (registered user) on Fri, 2010-03-26 20:00.

    Yes, this is a minor part of the config I forgot to post. It has been modified in the tutorial, thanks!

    The reason I use a "backend" section is to make it a bit more tidy and adding the possibility of extra PHP parsing servers.

    Submitted by Aswani (not registered) on Thu, 2011-10-27 12:45.

    this tutorial is very helpful, but my problem is, the server is not accepting HTTP GET variables more than 512 char long. i searched a lot but not able to find solution.

     please help me