Configure multiple sites with Varnish

ConfigurationCachingVarnish

Configuration Problem Overview


We have a server which needs to serve multiple domains though varnish e.g. example1.com, example2.com and example3.com

Our current .vcl file looks like this:

sub vcl_recv {
  set req.http.Host = "example1.com";    
  lookup;
}

How do I set the correct req.http.Host for the correct incoming request?

Configuration Solutions


Solution 1 - Configuration

You can support multiple frontend domains this way:

 backend example1 {
     .host = "backend.example1.com";
     .port = "8080";
 }
 backend example2 {
      .host = "backend.example2.com";
      .port = "8080";
 }
 sub vcl_recv {
    if (req.http.host == "example1.com") {
        #You will need the following line only if your backend has multiple virtual host names
        set req.http.host = "backend.example1.com";
        set req.backend = example1;
        return (lookup);
    }
    if (req.http.host == "example2.com") {
        #You will need the following line only if your backend has multiple virtual host names
        set req.http.host = "backend.example2.com";
        set req.backend = example2;
        return (lookup);
    }
 }

Solution 2 - Configuration

I'm using setup similar to Cristian's, but in if clauses I match req.http.host against regular expression:

#for www.example.com or example.com
if (req.http.host ~ "^(www\.)?example\.com$") {
        set req.backend = example_com;
        return (lookup);
}

#with any subdomain support
if (req.http.host ~ "^(.*\.)?example2\.com$") {
        set req.backend = example2_com;
        return (lookup);
}

Don't forget to set backends appropriately!

Solution 3 - Configuration

unable to add comment so here we go

slight modification for varnish 4

#for www.example.com or example.com
if (req.http.host ~ "^(www\.)?example\.com$") {
        set req.backend_hint = example_com;
        return (hash);
}

#with any subdomain support
if (req.http.host ~ "^(.*\.)?example2\.com$") {
        set req.backend_hint = example2_com;
        return (hash);
}

replace backend with backend_hint

Solution 4 - Configuration

I'd like to add a little more detail to both Cristian Vidmar and msurovcak's posts

The "(req.http.host == "example1.com") " Pattern:

We have used the pattern described to host tens to hundreds of sites per server.

You can continue with site specific custom rules throughout your entire config (vcl_fetch/vcl_backend_response, vcl_hash etc) using the

if (req.http.host == "example1.com") {

example wherever needed.

Combine this with a templating engine to allow customer specific configurations to be managed via individual files that contain their own logic (all wrapped with their site specific if blocks to isolate the code).

You then include each individual site block into the default.vcl using:

include "/etc/varnish/www.example1.com.vcl";

An optional enhancement to totally split backends:

If you are hosting totally different websites then split backends (and split cache) is a good way to go.

If the sites are similar (same codebase/js/css/images) it can be interesting to run a resources domain eg. resources.example.com that all sites use.

You can then have a single cache (and very high hit rate) across each of the common elements of multiple sites and still maintain differences on the individual www sites.

Another alternative to using split back ends:

Another option is to split out the Varnish instances via containers. Each then becomes it's own isolated world that is managed (and lives and dies) individually. This can be a good safety option and the overhead of multiple processes is minimal on modern infrastructure.

Some advantages of this is that you can then support different versions of Varnish and different Varnish startup parameters per instance.

This can be great for individual logging, leveraging different ESI modes per instance and individual memory/tuning configuration settings.

We do this at www.section.io and it also gives us the ability to run different containers in different geographical locations or the same containers in different locations to get as close as possible to geographically dispersed user bases.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTomView Question on Stackoverflow
Solution 1 - ConfigurationCristian VidmarView Answer on Stackoverflow
Solution 2 - ConfigurationmsurovcakView Answer on Stackoverflow
Solution 3 - ConfigurationhyenaView Answer on Stackoverflow
Solution 4 - ConfigurationmattnthatView Answer on Stackoverflow