Search code examples
varnishvarnish-vclvarnish-4

Varnish how to return same cache for multiple domains


MI have two domains pointing to the same nginx server. this is my setup and how I want to run my domains.

My problem is that When a user for example requests site1.com/page/ its cache is diffrent than site2.com/page.

I want both site1.com/page/ & site2.com/page/ to return the same cache so the server does not store cache twice.

my vcl setup is set to 127.0.0.1

backend default {
  .host = "127.0.0.1";
  .port = "8081";
}

Nginx

server {
        listen       8081;
        server_name  site1.com site2.com;

What rule or config can I add to make make varnish treat site1.com & site2.com the same? Basically I want varnish to ignore the hostname(domain) & cache base on the URL and other hash data.

my varnish version is 4.0


Solution

  • The vcl_hash subroutine in VCL is responsible for creating the hash that is used to lookup objects in the cache. The Varnish built-in VCL for vcl_hash goes as follows:

    sub vcl_hash {
        hash_data(req.url);
        if (req.http.host) {
            hash_data(req.http.host);
        } else {
            hash_data(server.ip);
        }
        return (lookup);
    }
    

    As you can see, it takes both the URL (through req.url) and the Host header (through req.http.host and server.ip if there is no host) to create the lookup hash.

    The Host header is important here because it identifies the site that needs to be cached. If you're accelerating multiple websites on a single Varnish server, the Host header ensures site1.com/page and site2.com/page don't share the same cache.

    You seem to want the exact opposite. This means that instead of relying on the built-in VCL, you have to specify a custom vcl_hash definition that will look like this:

    sub vcl_hash {
        hash_data(req.url);
        return (lookup);
    }
    

    This will share the cache between all websites and will only use the URL to identify objects in the cache.

    If you want to have more security in place, you can also share the cache between sites explicitly, rather than sharing the cache for every single site.

    Here's some example VCL code that only allows the cache to be shared between site1.com and site2.com:

    sub vcl_hash {
        if(req.http.host == "site1.com" || req.http.host == "site2.com") {
            hash_data(req.url);
            return (lookup);
        }
    }
    

    If the condition is not matched, no return statement is executed, which means the built-in VCL is still used.

    WARNING: I noticed that you use Varnish version 4. Please do not use this version as it is end-of-life. There are no more updates happening for this version and no security fixes. There are known security vulnerabilities for Varnish 4. Please upgrade to Varnish 6.0 LTS or one of the fresh releases.