HomeTechnology Varnish on CentOS 4 with Parallels Plesk

Varnish on CentOS 4 with Parallels Plesk

Posted in : Technology, Varnish on by : Richard Lamse

Varnish is a reversed proxy. Besides it can speed up the loading time of a web site, it’s also the ideal solution for load-balancing and providing access to applications servers without private IP address (thus not accessible directly from the internet). This document is limited to just installing Varnish on CentOS 4 and configuration for use with Parallels Plesk.  For more information on Varnish and its possibilities, please go to: http://www.varnish-cache.org

To use the latest version of Varnish (2.1 at the time of writing), you need pcre and pcre-devel installed. These packages are not available though the standard repositories of CentOS4.

Install this package as follow:

wget http://pub.medialogik.com/medialogik/CentOS/4/i386/i686/pcre-7.0-2.i686.rpm
wget http://pub.medialogik.com/medialogik/CentOS/4/i386/i686/pcre-devel-7.0-2.i686.rpm
rpm -Uvh pcre-7.0-2.i686.rpm pcre-devel-7.0-2.i686.rpm

Some other packages we need before we can start:

yum install glib-devel xorg-x11-devel

Next we can download Varnish and compile the sources for installation:

wget http://downloads.sourceforge.net/project/varnish/varnish/2.1.1/varnish-2.1.1.tar.gz
tar -xzvf varnish-2.1.1.tar.gz
cd varnish-2.1.1.tar.gz
./configure --exec-prefix=/usr
make
make check
make install

Next step is the configuration of  Varnish.  First you create a default configuration file:

mkdir /etc/varnish
vim /etc/varnish/default.vcl
# This is a basic VCL configuration file for varnish.  See the vcl(7)
# man page for details on VCL syntax and semantics.
#
# Default backend definition.  Set this to point to your content
# server.
#
backend default {
        .host = "1.2.3.4";
        .port = "6080";
}
#
# Below is a commented-out copy of the default VCL logic.  If you
# redefine any of these subroutines, the built-in logic will be
# appended to your code.
#
sub vcl_recv {
    if (req.http.x-forwarded-for) {
        set req.http.X-Forwarded-For =
            req.http.X-Forwarded-For ", " client.ip;
    } else {
        set req.http.X-Forwarded-For = client.ip;
    }
    if (req.request != "GET" &&
      req.request != "HEAD" &&
      req.request != "PUT" &&
      req.request != "POST" &&
      req.request != "TRACE" &&
      req.request != "OPTIONS" &&
      req.request != "DELETE") {
        /* Non-RFC2616 or CONNECT which is weird. */
        return (pipe);
    }
    if (req.request != "GET" && req.request != "HEAD") {
        /* We only deal with GET and HEAD by default */
        return (pass);
    }
    if (req.http.Authorization || req.http.Cookie) {
        /* Not cacheable by default */
        return (pass);
    }
    return (lookup);
}
#
sub vcl_pipe {
    # Note that only the first request to the backend will have
    # X-Forwarded-For set.  If you use X-Forwarded-For and want to
    # have it set for all requests, make sure to have:
    # set req.http.connection = "close";
    # here.  It is not set by default as it might break some broken web
    # applications, like IIS with NTLM authentication.
    return (pipe);
}
#
sub vcl_pass {
    return (pass);
}
#
sub vcl_hash {
    set req.hash += req.url;
    if (req.http.host) {
        set req.hash += req.http.host;
    } else {
        set req.hash += server.ip;
    }
    return (hash);
}
#
sub vcl_hit {
    if (!obj.cacheable) {
        return (pass);
    }
    return (deliver);
}
#
sub vcl_miss {
     return (fetch);
}
#
sub vcl_fetch {
    if (!beresp.cacheable) {
        return (pass);
    }
    if (beresp.http.Set-Cookie) {
        return (pass);
    }
    return (deliver);
}
#
sub vcl_deliver {
    return (deliver);
}
#
sub vcl_error {
    set obj.http.Content-Type = "text/html; charset=utf-8";
    synthetic {"
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
  <head>
    <title>"} obj.status " " obj.response {"</title>
  </head>
  <body>
    <h1>Error "} obj.status " " obj.response {"</h1>
    <p>"} obj.response {"</p>
    <h3>Guru Meditation:</h3>
    <p>XID: "} req.xid {"</p>
    <hr>
    <address>
       <a href="http://www.varnish-cache.org/">Varnish cache server</a>
    </address>
  </body>
</html>
"};
    return (deliver);
}

Replace the IP at .host for the public IP of your server. In this example Varnish will use the back end server at port 6080. You can change this to any available port.

Next you need to configure your Apache HTTP server to listen on the TCP port used as your back end server. To do this, you need to edit the Apache configuration:

vim /etc/httpd/conf/httpd.conf
Listen 6080

Next you need to edit every single httpd.include in the vhost directories and change the port 80 for each virtual host entry to port 6080. When this is completed you need to reload Apache HTTP server and start Varnish:

/etc/init.d/httpd reload
/usr/sbin/varnishd -f /etc/varnish/default.vcl -a :1.2.3.4:80 -s file,/tmp/varnish_storage.bin,1G

With multiple public IP addresses you can actually use Varnish only for a particular IP address. This is ideal if you only want to use reversed proxy for certain domains. To do this, you need to change the Apache HTTP configuration. For example:

vim /etc/httpd/conf/httpd.conf
Listen 1.2.3.4:6080
Listen 2.3.4.5:80
Listen 127.0.0.1:80

Next you need to edit the httpd.include for each domain that uses reversed proxy to change the TCP port 80 to 6080.

<aside id="foodrecipes_randompostwidget-2" class="widget blog-categories foodrecipes_randompostwidget"><h2 class="widget-title"> </h2>
</aside>