Previously I discussed getting Apache + PHP up and running, which provides the foundation for our new web server.  Next we’ll install Nginx as a front-end cache which will speed up the delivery of your website considerably – and use fewer resources while doing it!

Visitors who access your website will be served content via Nginx, where a cached version of your website will be served.  Only dynamic requests or content which the Nginx cache does not currently hold will be passed back to Apache to serve.  This keeps the system resources usage down, and the result is a fast and efficient serving process which can handle far more requests than Apache on it’s own.

Part 2 : Install Nginx as a cache & reverse proxy

Firstly, lets reconfigure Apache to act as the receiver for requests from Nginx, rather than the general public on port 80.  To do this make sure you are elevated to root permissions and run the following to open the Apache config with a text editor (vi):

vi /etc/httpd/conf/httpd.conf

If you aren’t familiar with vi you may have a hard time, but bear with me.  You need to search for ‘Listen 80′ which is the web servers default port, do this by typing:

/Listen\ 80

Then press Shift + A (begin editing at end of line) and type 80, so the full line reads:

Listen 8080

Next, press ‘Escape’ followed by

:wq

That’ll save the file.  It means “Write & Quit”.  Restart the web server with with following command:

/etc/init.d/httpd restart

2)  Install Nginx with Yum & Configure

Yum makes software management a breeze, simply issue the following command to install:

yum install nginx

Seriously that’s it.  Now lets edit the default nginx config using our friend ‘vi’ again.  Do this with:

vi /etc/nginx/nginx.conf

Below is my config, you can change to suit.  This will be fine for most serving environments, however:

user              nginx;
worker_processes  2;

pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

sendfile        on;
keepalive_timeout  5;
gzip on;
gzip_comp_level 2;
gzip_min_length 10;
gzip_proxied any;
gzip_types      text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript application/xhtml+xml;
# Need Vary on encoding though, otherwise caches may get confused
gzip_vary on;
gzip_disable "MSIE [1-6]\.";
gzip_http_version 1.1;

# Add server name for debugging.  Useful if you are running multiple caches
add_header X-Served-By $server_addr;
proxy_temp_path /var/tmp/nginx/tmp;
# Set cache-data file with a max-size of 1GB
proxy_cache_path /var/tmp/nginx/cache-data  levels=1:2   keys_zone=data:150m max_size=1024m;

# Set the validity time depending on HTTP code response.
proxy_cache_valid  200 302 5m;
proxy_cache_valid  301 1h;
proxy_cache_valid  404 30s;

upstream apache {
        server localhost:8080;
}

log_format common '$host $remote_addr - $remote_user [$time_local] '
                          '"$request" $status $body_bytes_sent '
                          '"$http_referer" "$http_user_agent"';

server {
        listen 80;
        server_name _;
        proxy_cache data;
        error_log  /var/log/nginx/error.log  info;
        access_log /var/log/nginx/access.log common;

    location / {
        # Proxy to apache backend
        proxy_pass http://apache;
        # Set header to be what we requested
        proxy_set_header        Host    $host;
        # Set proxy_cache expiry time
        proxy_cache_valid  200 302  5m;
        proxy_cache_valid  404      1m;
        proxy_cache_valid  301      1h;
        # Need this for snooping with tcpdump (turns off upstream compression)
        proxy_set_header        Accept-Encoding  "";
        # Set real IP header (needed for client IP detection in apache)
        proxy_set_header  X-Real-IP  $remote_addr;
        # Explicitly allow critical headers
        proxy_pass_header Set-Cookie;
        # Prevent 304 responses being returned from Apache and cached by nginx
        proxy_set_header If-None-Match "";
        }
    }
}

We’ll need to create the Nginx cache directory with the following:

mkdir -p /var/tmp/nginx

All going well you should be able to start Nginx with the following command:

/etc/init.d/nginx start

Now test by firing a web-browser at your VPS IP address once more, and you should be greeted with whatever your Apache is serving from /var/www/html.  The key difference is this will now be coming via a cached Nginx front-end.

You can confirm with the following command:

wget -qO- --save-headers YOURVPSIPADDRESS | head
You should see something like this if everything is working correctly
HTTP/1.1 200 OK
Server: nginx/0.8.54
Date: Tue, 30 Aug 2011 03:49:39 GMT
Content-Type: text/html
Content-Length: 28405
Last-Modified: Tue, 30 Aug 2011 03:45:02 GMT
Connection: keep-alive
Vary: Accept-Encoding
X-Served-By: YOUR SERVER IP HERE
That’s it!  We’ll focus on tightening down the service and adding some other important features, next time around.