vHosts (name or ip based) with varnish

Kristian Lyngstol kristian at varnish-software.com
Wed Jan 12 14:14:24 CET 2011


Hi,


On Wed, Jan 12, 2011 at 09:59:13AM +0100, Frank Helmschrott wrote:
> via google i came to this post on varnish-software.com regarding vhost
> solutions for varnish:
> http://www.varnish-software.com/blog/virtual-hosts-varnish
> 
> I'd like to have a similar solution with an 'as small as possible'
> master.vcl that does the if/elsif part. I'd like to have mostly
> different configurations for each host.

There are a few different approaches.

The basic issue is: Varnish has several entry points to VCL (vcl_recv,
vcl_fetch, etc), and you have to either have one VCL per function per site,
or have the if(req.http.host ~ ...) in each of the VCLs. If at all
possible, I'd go for the latter. Ie:

  # master.vcl
  include "site1.vcl";
  include "site2.vcl";

  # site1.vcl
  backend site1backend { .host = "foo1" };

  sub vcl_recv {
	  if (req.http.host ~ "site1") {
		  set req.backend = site1backend;
		  (... more site1 stuff ...)
	  }
  }

  sub vcl_deliver {
	  if (req.http.host ~ "site1") {
		  set resp.http.X-site = "Server by site 1";
	  }
  }


  # site2.vcl
  backend site2backend { .host = "foo1" };

  sub vcl_recv {
	  if (req.http.host ~ "site2") {
		  set req.backend = site2backend;
		  (... more site2 stuff ...)
	  }
  }

  sub vcl_deliver {
	  if (req.http.host ~ "site2") {
		  set resp.http.X-site = "Server by site 2";
	  }
  }

It adds a bit of extra indentation in each file, but the benefit is that
you get full use of VCL in all the included files - for better or worse.
The alternative is:

   # master.vcl
   backend site1 ....
   backend site2 ....
   sub vcl_recv {
	   if (req.http.host ~ "site1") {
		   set req.backend = site1;
		   include "site1recv.vcl";
	   } elif (req.http.host ~ "site2") {
		   set req.backend = site2;
		   include "site2recv.vcl";
	   }
   }
   sub vcl_deliver {
	   if (req.http.host ~ "site1") {
		   include "site1deliver.vcl";
	   } elif (req.http.host ~ "site2") {
		   include "site2deliver.vcl";
	   }
   }

(followed by logic for vcl_recv in site1recv.vcl, site2recv.vcl and so
forth).

The benefit here is that all the "which site is this" control is contained
in the master file, but you also get a large amount of _different_ files
and less direct control in the included files...

But for further reading, you really must go through the Varnish tutorial at 
http://www.varnish-cache.org/docs/2.1/

- Kristian
PS: I didn't even pretend to proof read the VCL - consider it pseudo-code




More information about the varnish-misc mailing list