How to Setup Varnish 3.0 in Front of Nginx, PHP5.4 (PHP-FPM)

In web hosting one common challenge for server administrators is how to effectively manage the load on their servers, especially when running resource-intensive applications like WordPress. The solution? Implementing a caching HTTP reverse proxy, such as Varnish Cache, in front of your Nginx and PHP5.4 (PHP-FPM) web server.

Varnish Cache is a popular web accelerator that can work alongside either Apache or Nginx web servers. In this tutorial, we will focus on setting up Varnish to run on port 80, while Nginx operates on port 8080. This setup can significantly speed up your website’s delivery to visitors, reduce CPU time, and minimize database requests and file lookups.

By implementing Varnish Cache, you can enjoy several benefits. It can reduce server CPU load and time, increase website load speed, handle a large number of website visitors, and even support load balancing. For more information on the benefits and features of Varnish Cache, you can visit this page.

This tutorial will guide you through the process of setting up Varnish 3.0 in front of an Nginx, PHP5.4 (PHP-FPM) web server. The steps have been tested on CentOS 6, CentOS 7, Oracle Linux 7, and RHEL 7. If you are looking for other proxy server software options, you can check out this page.

See also  How to Implement Basic Protection Against DDoS Attacks for Nginx

Step 1: Setup Nginx, PHP5.4 (PHP-FPM) as Web Server

Before we can install and configure Varnish, we need to ensure that Nginx and PHP5.4 (PHP-FPM) are properly set up as your web server. If you need a guide on how to do this, you can refer to this tutorial.

Step 2: Install Varnish

The next step is to install Varnish on your server. This involves downloading the Varnish release package and installing it using the package manager.

[root@vps ~]# wget https://repo.varnish-cache.org/redhat/varnish-3.0/el6/noarch/varnish-release/varnish-release-3.0-1.el6.noarch.rpm
[root@vps ~]# rpm -Uvh varnish-release-3.0-1.el6.noarch.rpm
[root@vps ~]# yum install varnish -y

Step 3: Configure Varnish

After installing Varnish, we need to configure it to work with our Nginx web server. This involves modifying the Varnish configuration files to specify that Nginx is running as the backend server on localhost at port 8080, while Varnish will run in front of it listening on port 80.

Modify /etc/sysconfig/varnish:

[root@vps ~]# vim /etc/sysconfig/varnish

Add the following. If your VPS running SSD disk, you can select varnish_storage as a cache method instead of memory (-s malloc):

..
..
DAEMON_OPTS="-a :80 \
             -T localhost:6082 \
             -f /etc/varnish/default.vcl \
             -u varnish -g varnish \
             -S /etc/varnish/secret \
             -p thread_pool_add_delay=2 \
             -p thread_pools=2 \
             -p thread_pool_min=400 \
             -p thread_pool_max=4000 \
             -p session_linger=50 \
             -p sess_workspace=262144 \
             -s file,/var/lib/varnish/varnish_storage.bin,512m"
..
..
VARNISH_LISTEN_PORT=80
..
..

Modify /etc/varnish/default.vcl:

[root@vps ~]# vim /etc/varnish/default.vcl

Add below:

backend default {
    .host = "127.0.0.1";
    .port = "8080";
    .connect_timeout = 600s;
    .first_byte_timeout = 600s;
    .between_bytes_timeout = 600s;
    .max_connections = 800;
}


acl purge {
	"127.0.0.1";
}

sub vcl_recv {


	# Allow purge requests
	if (req.request == "PURGE") {
        if (!client.ip ~ purge) {
            error 405 "Not allowed.";
        }
        ban("req.url ~ ^" + req.url + " && req.http.host == " + req.http.host);
        return(lookup);
    }

	# Add header for sending client ip to backend
	set	req.http.X-Forwarded-For = client.ip;

	# Normalize	content-encoding
	if (req.http.Accept-Encoding) {
        if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|lzma|tbz)(\?.*|)$") {
            remove req.http.Accept-Encoding;
        } elsif (req.http.Accept-Encoding ~ "gzip") {
            set req.http.Accept-Encoding = "gzip";
        } elsif (req.http.Accept-Encoding ~ "deflate") {
            set	req.http.Accept-Encoding = "deflate";
        } else {
            remove req.http.Accept-Encoding;
        }
    }

    # Remove cookies and query string for real static files
    if (req.url ~ "^/[^?]+\.(gif|jpg|jpeg|swf|css|js|txt|flv|mp3|mp4|pdf|ico|png|gz|zip|lzma|bz2|tgz|tbz)(\?.*|)$") {
       unset req.http.cookie;
       set req.url = regsub(req.url, "\?.*$", "");
    }

    # Don't cache admin
    if (req.url ~ "((wp-(login|admin|comments-post.php|cron.php))|login)" || req.url ~ "preview=true" || req.url ~ "xmlrpc.php") {
        return (pass);
    } else {
    	unset req.http.cookie;
    }
}

sub vcl_hit {
	# purge cached objects from memory
	if (req.request == "PURGE") {
		purge;
		error 200 "Purged";
	}
}

sub vcl_miss {
	# purge cached objects varients from memory
	if (req.request == "PURGE") {
		purge;
		error 404 "Purged varients";
	}
}

sub vcl_fetch {
	# Dont cache admin
	if (req.url ~ "(wp-(login|admin|comments-post.php|cron.php))|login" || req.url ~ "preview=true" || req.url ~ "xmlrpc.php") {
    	    return (deliver);
	} else {
    	    if ( beresp.ttl > 0s ) {
    	        unset beresp.http.set-cookie;
    	    }
	}
}


sub vcl_deliver {

	# Remove unnecessary headers
	remove resp.http.Server;
	remove resp.http.X-Powered-By;
	remove resp.http.X-Varnish;
	remove resp.http.Via;

	# DIAGNOSTIC HEADERS
	if (obj.hits > 0) {
		set resp.http.X-Cache = "HIT";
	} else {
		set resp.http.X-Cache = "MISS";
	}

}

Step 4: Configure NGINX to work with Varnish:

Configure default.conf:

[root@vps ~]# vim /etc/nginx/conf.d/default.conf

Add the following :

..
server {
    listen       127.0.0.1:8080;
    server_name  localhost;
..

Configure common.conf:

[root@vps ~]# vim /etc/nginx/conf.d/common.conf
..
..

listen 127.0.0.1:8080;
..
..

Configure Vhost for domain example.com:

[root@vps ~]# vim /etc/nginx/sites-available/example.com.conf

Change listen to 127.0.0.1:8080; :

server {
listen       127.0.0.1:8080;
    server_name example.com;
    rewrite ^/(.*)$ http://www.example.com/$1 permanent;
}
..

Restart NGINX, php-fpm and Varnish:

[root@vps ~]# service nginx restart; service php-fpm restart; service varnish restart

Make sure NGINX listening to port 8080 and Varnish port 80:

[root@vps ~]# netstat -plunt  | grep LISTEN
tcp        0      0 0.0.0.0:80                  0.0.0.0:*                   LISTEN      3119/varnishd
tcp        0      0 127.0.0.1:8080              0.0.0.0:*                   LISTEN      3065/nginx

Conclusion

This tutorial is just the beginning of your journey with Varnish Cache. There’s a lot more to explore and learn. For instance, you might want to look into other types of web servers, such as Apache, Litespeed, and more. You can find more information on these topics on this page.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *