Varnish + SSL + Multiple Sub-Domains on Apache

March 19, 2016 832 views
Apache Load Balancing Ubuntu

So I run three separate Ghost blog/NodeJS websites. I currently use Apache, listening on port 80 and reverse proxy-ing to each specific NodeJS server. All of these rewrite to HTTPS, so no browsing the site with HTTP.

I would like to set up Varnish in front of the Apache server. Now I know it's not really important to set up Varnish-- I have a no-name website with very little traffic. It's already convoluted that I have Apache running with NodeJS behind it.

How would I be able to set up Varnish to pipe HTTPS traffic to the Apache server? I saw that Varnish doesnt really handle HTTPS traffic without using nginx. I would rather not have another server running on top of Apache and NodeJS.

1 Answer

There would be absolutely no point in making Varnish just pipe the data to the backend. What most people do is terminate the TLS-connection in Apache2 or Nginx, then proxy that to Varnish, which in turn proxies it to your web server. That way you can cache the data in Varnish.

You can also make Varnish do redirect if the traffic is not going over TLS by looking for X-Forwarded-Proto-headers. Also remember to hash based on the X-Forwarded-Proto-headers, or else you will have a very strange cache, as the objects will look the same to Varnish.

  • Would it make more sense ripping out Apache and putting in nginx? I've been meaning to learn how to use nginx. This is all just for a personal site, so rebuilding doesn't kill anything.

    • I think you should use what you're comfortable with. I happen to be one of those pesky nginx-fanboys, but really, it's just a matter of taste. You should definitively give it a go, but don't expect it to be the be-all and end-all kind of software.

      It can however be smart, for debugging purposes, to use something else to terminate the TLS-connection. Like stunnel, haproxy or pound. Makes it a little easier to read log files when you're investigating problems. It can be a little hard to trace down the issue when things go back end forth.

      In Varnish you'd do something like this to redirect traffic from non-TLS to TLS.

      sub vcl_recv {
          if ( ~ "^(www\.)?domain\.com$" && req.http.X-Forwarded-Proto !~ "(?i)https") {
              return (synth(750, ""));
      sub vcl_synth {
          if (resp.status == 750) {
              set resp.status = 301;
              set resp.http.Location = "https://" + + req.url;

      And since Varnish doesn't care about what protocol you are using, or rather, doesn't know at all, you also have to hash the cached data based on something that actually differs. Since we're setting (or should be setting) the X-Forwarded-Proto-header (along with the X-Forwarded-For-header) we can use that to differentiate the cached data.

      sub vcl_hash {
          if (req.http.X-Forwarded-Proto) {

      As you can imagine varnish is a really powerful product. Even more so when you start using the control terminal or purge-requests to maintain your cache so that things pages are updated when, say, someone makes a comment or you update a post.

      • I've been meaning to learn how to use nginx for a while now. I literally rebuilt my server two days ago for fun. I'll into getting nginx in its place.

Have another answer? Share your knowledge.