Subscribe via RSS or Subscribe via Email

Lightning Fast PHP Server With Nginx, eAccelerator, and Varnish

written by Travis Berry


In the word of servers, Apache is still the undisputed king. It’s extendability and ability to run anything you can throw at it has led to it being the number one most used server in the world. Just because it has large numbers though, doesn’t mean it’s the best in terms of performance.

When running a site with lots of traffic, Apache can quickly grow into a large beast. This can be overcome by throwing more machines (and money) at the problem, but for many companies and people, that simply isn’t an option. Instead why not squeeze every piece of performance that you can out of your existing tech.

Enter Nginx. “Nginx is known for its high performance, stability, rich feature set, simple configuration, and low resource consumption.” In other words, it will run faster and more efficiently than Apache.

Installing Nginx on Ubuntu is fairly simple.

A simple

sudo apt-get install nginx

will get you started.

Now edit the file in /etc/nginx/sites-available/default

change it to

# You may add here your
# server {
#       ...
# }
# statements for each of your virtual hosts

server {
    listen   8080;
    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;
}

        #error_page  404  /404.html;

        # redirect server error pages to the static page /50x.html
        #
        #error_page   500 502 503 504  /50x.html;
        #location = /50x.html {
        #       root   /var/www/nginx-default;
        #}

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
                #proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
                #fastcgi_pass   127.0.0.1:9000;
                #fastcgi_index  index.php;
                #fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
                #includefastcgi_params;



# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
#listen   8000;
#listen   somename:8080;
#server_name  somename  alias  another.alias;

#location / {
#root   html;
#index  index.html index.htm;
#}
#}


# HTTPS server
#
#server {
#listen   443;
#server_name  localhost;
#ssl  on;
#ssl_certificate  cert.pem;
#ssl_certificate_key  cert.key;

#ssl_session_timeout  5m;

#ssl_protocols  SSLv3 TLSv1;
#ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;
#ssl_prefer_server_ciphers   on;

#location / {
#root   html;
#index  index.html index.htm;
#}
#}

This assumes your root web folder is /var/www. You’ll also notice I have it set to listen on port 8080 and not the normal 80. This comes into play later when we setup of Varnish, so just go with me for now.

Now we need to get PHP installed so we can actually serve PHP files.

As usual start with

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

then

sudo apt-get install php5-fpm php5-cgi

You may have to add deb http://php53.dotdeb.org stable all to your packages list for php5-fpm and php5-cgi to show up.

Before configuring PHP let’s install eAccelerator. “eAccelerator is a free open-source PHP accelerator & optimizer. It increases the performance of PHP scripts by caching them in their compiled state, so that the overhead of compiling is almost completely eliminated. It also optimizes scripts to speed up their execution. eAccelerator typically reduces server load and increases the speed of your PHP code by 1-10 times.”

First

sudo apt-get install php5-dev

then

sudo apt-get install make

Now cd into /tmp/

wget http://bart.eaccelerator.net/source/0.9.6.1/eaccelerator-0.9.6.1.tar.bz2

tar xvjf eaccelerator-0.9.6.1.tar.bz2

cd eaccelerator-0.9.6.1/

sudo phpize

sudo ./configure –enable-eaccelerator=shared

sudo make

sudo make install

Now edit /etc/php5/fpm/php.ini

and right under the [PHP] block add

; eAccelerator configuration
; Note that eAccelerator may also be installed as a PHP extension or as a zend_$
; If you are using a thread safe build of PHP you must use
; zend_extension_ts instead of zend_extension
;extension                       = "/usr/lib/php5/20090626+lfs/eaccelerator.so"
zend_extension                  = "/usr/lib/php5/20090626+lfs/eaccelerator.so"
eaccelerator.shm_size           = "16"
eaccelerator.cache_dir          = "/var/cache/eaccelerator"
eaccelerator.enable             = "1"
eaccelerator.optimizer          = "1"
eaccelerator.check_mtime        = "1"
eaccelerator.debug              = "0"
eaccelerator.filter             = ""
eaccelerator.shm_max            = "0"
eaccelerator.shm_ttl            = "0"
eaccelerator.shm_prune_period   = "0"
eaccelerator.shm_only           = "0"
eaccelerator.compress           = "1"
eaccelerator.compress_level     = "9"
eaccelerator.allowed_admin_path = "/var/www/eaccelerator"

Now restart PHP

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

Then restart Nginx

sudo /etc/init.d/nginx restart

Now if you hit http://localhost:8080/index.php you should see your site.

The only thing left to setup at this point is Varnish.

“Varnish store web pages in memory so the web servers don’t have to create the same web page over and over again. The web server only recreate a page when it is changed. Additionally Varnish can serve web pages much faster then any application server is capable of – giving the website a significant speed up.”

Install with

sudo apt-get install varnish

After install run

pkill varnishd

to make sure it’s not running while we configure it.

Now run

sudo varnishd -f /etc/varnish/default.vcl -s malloc,1G -T 127.0.0.1:2000

Varnish should now be running. Check by typing

varnishlog

If you see a series of lines then Varnish should be working.

You can run one more test by going to your browser and reloading the page.

If you see results like

12 SessionOpen  c 192.168.10.101 51732 :80
   12 ReqStart     c 192.168.10.101 51732 1440203205
   12 RxRequest    c GET
   12 RxURL        c /favicon.ico
   12 RxProtocol   c HTTP/1.1
   12 RxHeader     c Host: www.ironyogistudios.com
   12 RxHeader     c User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.10) Gecko/20100914 Firefox/3.6.10
   12 RxHeader     c Accept: image/png,image/*;q=0.8,*/*;q=0.5
   12 RxHeader     c Accept-Language: en-us,en;q=0.5
   12 RxHeader     c Accept-Encoding: gzip,deflate
   12 RxHeader     c Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
   12 RxHeader     c Keep-Alive: 115
   12 RxHeader     c Connection: keep-alive

Then Varnish is correctly intercepting your requests. Varnish is getting the requests on port 80 forwarding them to Nginx if needed through port 8080, which is why we set it to 8080 earlier. You can set the port to foward in /etc/varnish/default.vcl. You can learn more about the setup and optimization of Varnish here.

You should now have a lighting fast PHP server. This setup is a pretty basic configuration so I’m sure by tweaking each individual component to your needs would get even more performance out of it. Compared to a base Apache config, though, this is fantastic.

If you have some optimization techniques, or have any questions, let me know in the comments.

If you liked this article, need freelance work completed, or just want to say “Hi”, contact me here.

I’m just a guy interested in all things design and web related. You should contact me about about this article, for freelance work, or for any reason.

11 Comments

  1. Aymen BEN, October 19, 2010:

    I find this article very interesting and would like to ask if you have any other suggestion specific to improving FLV or other video formats streaming performance…

  2. Brian, November 30, 2010:

    Great tutorial works like a charm… Question How can i get nginx and vanish to auto start when the server boots up?

    Thanks
    Brian

  3. Travis Berry, December 11, 2010:
  4. Adam T., December 27, 2010:

    Hi thanks for this awesome tutorial –at least it looks awesome for me, i’m just not managing to pull it off! i get dependency issues which I can’t seem to get past. Particularly with php5-cli, which depends on: libicu38 (>=3.8-5) but it is not installable

    and Depends: libkrb53 (>=1.6.dfsg.2) but it is not installable

    E: broken packages

    No idea how to get past this, and trust me, your my last resort lol, i’ve looked everywhere.. your help would be appreciated as I really want to get this server set up (its an awesome setup)

    thnx and peace

  5. Adam T., December 27, 2010:

    php5-cgi: Depends: libicu38 (>= 3.8-5) but it is not installable
    Depends: libkrb53 (>= 1.6.dfsg.2) but it is not installable
    php5-fpm: Depends: libicu38 (>= 3.8-5) but it is not installable
    Depends: libkrb53 (>= 1.6.dfsg.2) but it is not installable

  6. Adam T., December 28, 2010:

    okay folks happy to announce the fix to the problems I have faced with this installation:
    the two dependencies problems libicu38 and libkrb53 can be fixed by adding this:
    ‘deb http://security.ubuntu.com/ubuntu jaunty-security main’
    to your sources list (/etc/apt/sources.lsit) and running ‘apt-get update’ after and then installing each dependency.

    and you may also need libtool which can be installed following these instructions:

    For Libtool
    ‘apt-get isntall autotools-dev’
    (you may be asked to type ‘apt-get -f install’ if so, then type it and proceed)
    cd ~
    wget http://us.archive.ubuntu.com/ubuntu/pool/main/libt/libtool/libtool_1.5.26-1ubuntu1_i386.deb
    dpkg -i libtool_1.5.26-1ubuntu1_i386.deb

    finally the last problem encountered was that nginx was giving me 404 errors when accessing php files, and the fix was that
    ‘include fastcgi_params;’ in the ‘/etc/nginx/sites-available/default’ file, this inclusion is redundant (because the params are being declared, and so the redundancy was causing errors).

    After all this, its working like a charm :)
    peace

  7. Travis Berry, January 1, 2011:

    Thanks for the update Adam. I actually ran into this problem recently and had to fight to get it to work. I forgot to post my solution, so I’m glad you’ve provided one here. Thanks.

  8. den, January 6, 2011:

    You can use a memcached also to put a server on a next level of effectivenes.

  9. Thanh, January 15, 2011:

    I skipped most of the tutorial since I have a working nginx/php-fpm set up. So I tried to install and run varnish. I noticed a couple of things… there was no default.vcl file but instead, there was a vcl.conf file so I tried that. varnish looked like it running but when I go to the page, nothing is displayed but I see activity in varnishlog. How do I go about debugging this?

  10. Travis Berry, January 20, 2011:

    I’m not sure about the missing default.vcl file. This guy has a good one you could copy. default.vcl. One thing you could check and may have missed is setting the nginx server to port 8080 or anything other than 80.

  11. dateksa, July 23, 2011:

Leave a comment


back to blog