Virtual host based on includes

Johnny Halfmoon jhalfmoon at milksnot.com
Wed Jan 12 22:02:48 CET 2011


On 01/12/2011 04:08 PM, Jonathan Lopez wrote:
> Hello,
> 
> I´m trying to create a main config file that includes an another file to the specific configuration for each virtual host, an example:
>
> sub vcl_recv {
>         set req.http.Host = regsub(req.http.Host, "^www\.", "");
>         include "/etc/varnish/" req.http.host “.vcl”;
> }
> 
> Then, each domain has a customized VCL in his own file.
> Is this possible? I have tried everything but with no success. I don’t want to make a huge if/else condition for each domain (virtual host).
> 

Hi Jonathan,

what you try to do here is not possible:

> include "/etc/varnish/" req.http.host “.vcl”;

Varnish does not include in runtime, but at compile time, that is, when the configs actually get loaded. What you could do is the following:

main.vcl
  <place your default vcl settings here>
  include "/etc/varnish/sites.vcl
  include "/etc/varnish/catch-all.vcl

sites.vcl
  include "/etc/varnish/sites/site1.vcl
  include "/etc/varnish/sites/site2.vclT
  include etc...

catch-all.vcl
  <place any code you want to append to the end of any vcl_* routine here>

site1.vcl
  backend www_site1_com  { .host   =  "1.2.3.4"; }   
  sub vcl_recv
  {
    if (req.http.host ~ "^www.site1.com$")  { set req.backend = www_site1_com; }
  }
  sub vcl_deliver {
    if (req.backend == www_site1_com ) { 
      <do something>;
    }   
  }

site2.vcl
  backend www_site2_com  { .host   =  "11.22.33.44"; }   
  sub vcl_recv
  {
    if (req.http.host ~ "^www.site2.com$")  { set req.backend = www_site2_com; }
  }
  sub vcl_deliver {
    if (req.backend == www_site2_com ) { 
      <do something else>;
    }   
  }

In short this is what we do in the above code:
  - define a main.vcl where you set a bunch of default stuff for all sites, like ttl, grace time etc...
  - from main.vcl you include sites.vcl, which in its turn includes the vcls of all your sites. This keeps main.vcl tidy
  - main.vcl also includes catch-all.vcl, which may and probably will contain code that is to be executed after all site configs have been handled
  - each site config does the stuff it needs to do for that site
  - the main idea behind all this is that varnish appends all the different code blocks in the order they are included. So if you were to define a vcl_receive and vcl_deliver in all your vcl files, this is how they would be compiled by varnish:

vcl_receive {
  vcl_receive of main.vcl
  vcl_recieve of sites.vcl
  vcl_receive of site1.vcl
  vcl_receive of site2.vcl
  vcl_receive of catch-all
}

vcl_deliver {
  vcl_deliver of main.vcl
  vcl_deliver of sites.vcl
  vcl_deliver of site1.vcl
  vcl_deliver of site2.vcl
  vcl_deliver of catch-all
}

  - NOTE: take care that you always do a " if (req.backend == www_sitename_com ) check in every siteconfig you define, like you can see in the vcl_deliver code of the site1.vcl example. You need to do this to check what site you are handling at that moment. If you do not do that check, the code you define will be run for every site that is in your config.

Ik hope that helps.

Cheers,

Johnny




More information about the varnish-misc mailing list