Varnish Cache

Installing Varnish Cache on a cPanel Server

I’ve recently added Varnish Cache to my server with cPanel installed. Varnish Caching is now installed server-wide. It acts as an invisible intermediary between clients and the server and delivers some major speed improvements, noticeably to Magento and Drupal websites.

The Varnish install script created by Shubham Mathur worked very well but it currently doesn’t consider additional IPs. Also, you’ll need something to amend the $_SERVER['REMOTE_ADDR'] server variable to show the client’s IP address and not the server’s.

So to get Varnish working correctly across multiple IPs (required when you’re hosting TLS websites), here is my step-by-step guide:

  1. In Shell, run:
    wget https://raw.githubusercontent.com/itseasy21/w3tools-varnish/master/install.sh -O ./varnish-install.sh
    sh ./varnish-install.sh
  2. Edit the Varnish configuration file located at /etc/varnish/default.vcl (see below)
  3. Install mod_remoteip either using EasyApache or collect the files from GitHub.
  4. Set Apache configuration to load mod_remoteip (I recommend adding it to pre_main_global.conf):
    LoadModule remoteip_module modules/mod_remoteip.so
    RemoteIPHeader X-Forwarded-For
  5. Restart Apache and Varnish:
    /usr/local/apache/bin/apachectl graceful
    /etc/init.d/varnish restart

Here is the default varnish configuration file. I’d recommend copying the original (fully commented out) version before starting on this one.

backend default {
        .host = "12.34.50.01";
        .port = "82";
}
backend site1 {
        .host = "12.34.59.01";
        .port = "82";
}
backend site2 {
        .host = "12.34.59.02";
        .port = "82";
}

sub vcl_recv {
        if (req.restarts == 0) {
                remove req.http.X-Forwarded-For;
                set req.http.X-Forwarded-For = client.ip;
        }

        if (server.ip == "12.34.59.01" || req.http.host ~ "website1\.com" ) {
                set req.backend = site1;
        }
        else if (server.ip == "12.34.59.02" || req.http.host ~ "website2\.com") {
                set req.backend = site2;
        }
        else {
                set req.backend = default;
        }
        if (req.request != "GET" &&
                req.request != "HEAD" &&
                req.request != "PUT" &&
                req.request != "POST" &&
                req.request != "TRACE" &&
                req.request != "OPTIONS" &&
                req.request != "DELETE") {
                return (pipe);
        }

        if (req.request != "GET" && req.request != "HEAD") {
                return (pass);
        }

        if (req.http.Authorization || req.http.Cookie) {
                return (pass);
        }

        if (req.request == "GET" && req.url ~ "\.(css|gif|jpg|jpeg|bmp|png|ico|img|tga|wmf)$") {
                remove req.http.cookie;
        }

        return (lookup);
}

sub vcl_error {
        set obj.http.Content-Type = "text/html; charset=utf-8";
        set obj.http.Retry-After = "5";
        synthetic {"
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>"} + obj.status + " " + obj.response + {"</title>
<style type="text/css">
body,td,th {
        font-family: "Gill Sans", "Gill Sans MT", "Myriad Pro", "DejaVu Sans Condensed", Helvetica, Arial, sans-serif;
        color: #646464;
}
body {
        background-color: #CFCFCF;
}
</style>
</head>

<body>
<h1>"} + obj.status + " " + obj.response + {"</h1>
<h2>Varnish Error</h2>
<p><strong>XID:</strong> "} + req.xid + {"</p>
<p>Please try again momentarily</p>
</body>
</html>
"};
    return (deliver);
}

You can probably see where your IP address will fit in and the names for these corresponding websites – change the regular expresssion to match more precisely. The last function vcl_error is completely optional.

I will update this post when Shubham amends his script. Have a look at its source code if you need to reset the default Apache port.

Last updated on

Leave a Reply

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