Magento 2 Varnish caching per instance












1















I have a Magento v2.2.6 webshop running and I want Varnish on that. Now I installed Varnish and it seems to be active. But I have a (big) problem.



How Varnish should work is that it caches pages as soon as one person loads the page/files. The problem I have right now is that the pages are cached again for each person. (the pages are unique to each person/connection)



So if I load the home page twice on the same device the page is cached. But if I go to the home page on my phone the page needs to be cached again.



I'm pretty sure that this has something to do with the cookies of the webshop. Since Magento 2 saves everything in one big cookie.
Also the request headers are:



cache-control: no-store, no-cache, must-revalidate, max-age=0


And I don't think it should be like that..



To give you guys a beter idea, here is the varnish.vcl I'm using right now. It's the default one for Magento 2 except that it always shows a HIT or MISS. (The .host is different but I'm not going post that IP here)



vcl 4.0;

import std;
# The minimal Varnish version is 4.0
# For SSL offloading, pass the following header in your proxy server or load balancer: 'X-Forwarded-Proto: https'

backend default {
.host = "localhost";
.port = "8080";
.first_byte_timeout = 600s;
.probe = {
.url = "/pub/health_check.php";
.timeout = 2s;
.interval = 5s;
.window = 10;
.threshold = 5;
}
}

acl purge {
"localhost";
}

sub vcl_recv {
if (req.method == "PURGE") {
if (client.ip !~ purge) {
return (synth(405, "Method not allowed"));
}
# To use the X-Pool header for purging varnish during automated deployments, make sure the X-Pool header
# has been added to the response in your backend server config. This is used, for example, by the
# capistrano-magento2 gem for purging old content from varnish during it's deploy routine.
if (!req.http.X-Magento-Tags-Pattern && !req.http.X-Pool) {
return (synth(400, "X-Magento-Tags-Pattern or X-Pool header required"));
}
if (req.http.X-Magento-Tags-Pattern) {
ban("obj.http.X-Magento-Tags ~ " + req.http.X-Magento-Tags-Pattern);
}
if (req.http.X-Pool) {
ban("obj.http.X-Pool ~ " + req.http.X-Pool);
}
return (synth(200, "Purged"));
}

if (req.method != "GET" &&
req.method != "HEAD" &&
req.method != "PUT" &&
req.method != "POST" &&
req.method != "TRACE" &&
req.method != "OPTIONS" &&
req.method != "DELETE") {
/* Non-RFC2616 or CONNECT which is weird. */
return (pipe);
}

# We only deal with GET and HEAD by default
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}

# Bypass shopping cart, checkout and search requests
if (req.url ~ "/checkout" || req.url ~ "/catalogsearch" || req.url ~ "/onestepcheckout" || req.url ~ "/customer") {
return (pass);
}

# Bypass health check requests
if (req.url ~ "/pub/health_check.php") {
return (pass);
}

# Set initial grace period usage status
set req.http.grace = "none";

# normalize url in case of leading HTTP scheme and domain
set req.url = regsub(req.url, "^http[s]?://", "");

# collect all cookies
std.collect(req.http.Cookie);

# Compression filter. See https://www.varnish-cache.org/trac/wiki/FAQ/Compression
if (req.http.Accept-Encoding) {
if (req.url ~ ".(jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf|flv)$") {
# No point in compressing these
unset req.http.Accept-Encoding;
} elsif (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} elsif (req.http.Accept-Encoding ~ "deflate" && req.http.user-agent !~ "MSIE") {
set req.http.Accept-Encoding = "deflate";
} else {
# unkown algorithm
unset req.http.Accept-Encoding;
}
}

# Remove Google gclid parameters to minimize the cache objects
set req.url = regsuball(req.url,"?gclid=[^&]+$",""); # strips when QS = "?gclid=AAA"
set req.url = regsuball(req.url,"?gclid=[^&]+&","?"); # strips when QS = "?gclid=AAA&foo=bar"
set req.url = regsuball(req.url,"&gclid=[^&]+",""); # strips when QS = "?foo=bar&gclid=AAA" or QS = "?foo=bar&gclid=AAA&bar=baz"

# Static files caching
if (req.url ~ "^/(pub/)?(media|static)/") {
# Static files should not be cached by default
# return (pass);

# But if you use a few locales and don't use CDN you can enable caching static files by commenting previous line (#return (pass);) and uncommenting next 3 lines
unset req.http.Https;
unset req.http.X-Forwarded-Proto;
unset req.http.Cookie;
}

return (hash);
}

sub vcl_hash {
if (req.http.cookie ~ "X-Magento-Vary=") {
hash_data(regsub(req.http.cookie, "^.*?X-Magento-Vary=([^;]+);*.*$", "1"));
}

# For multi site configurations to not cache each other's content
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}

# To make sure http users don't see ssl warning
if (req.http.X-Forwarded-Proto) {
hash_data(req.http.X-Forwarded-Proto);
}

}

sub vcl_backend_response {

set beresp.grace = 3d;

if (beresp.http.content-type ~ "text") {
set beresp.do_esi = true;
}

if (bereq.url ~ ".js$" || beresp.http.content-type ~ "text") {
set beresp.do_gzip = true;
}

if (beresp.http.X-Magento-Debug) {
set beresp.http.X-Magento-Cache-Control = beresp.http.Cache-Control;
}

# cache only successfully responses and 404s
if (beresp.status != 200 && beresp.status != 404) {
set beresp.ttl = 0s;
set beresp.uncacheable = true;
return (deliver);
} elsif (beresp.http.Cache-Control ~ "private") {
set beresp.uncacheable = true;
set beresp.ttl = 86400s;
return (deliver);
}

# validate if we need to cache it and prevent from setting cookie
# images, css and js are cacheable by default so we have to remove cookie also
if (beresp.ttl > 0s && (bereq.method == "GET" || bereq.method == "HEAD")) {
unset beresp.http.set-cookie;
}

# If page is not cacheable then bypass varnish for 2 minutes as Hit-For-Pass
if (beresp.ttl <= 0s ||
beresp.http.Surrogate-control ~ "no-store" ||
(!beresp.http.Surrogate-Control &&
beresp.http.Cache-Control ~ "no-cache|no-store") ||
beresp.http.Vary == "*") {
# Mark as Hit-For-Pass for the next 2 minutes
set beresp.ttl = 120s;
set beresp.uncacheable = true;
}

return (deliver);
}

sub vcl_deliver {
#if (resp.http.X-Magento-Debug) {
if (resp.http.x-varnish ~ " ") {
set resp.http.X-Magento-Cache-Debug = "HIT";
set resp.http.Grace = req.http.grace;
} else {
set resp.http.X-Magento-Cache-Debug = "MISS";
}
#} else {
unset resp.http.Age;
#}

# Not letting browser to cache non-static files.
if (resp.http.Cache-Control !~ "private" && req.url !~ "^/(pub/)?(media|static)/") {
set resp.http.Pragma = "no-cache";
set resp.http.Expires = "-1";
set resp.http.Cache-Control = "no-store, no-cache, must-revalidate, max-age=0";
}

unset resp.http.X-Magento-Debug;
unset resp.http.X-Magento-Tags;
unset resp.http.X-Powered-By;
unset resp.http.Server;
unset resp.http.X-Varnish;
unset resp.http.Via;
unset resp.http.Link;
}

sub vcl_hit {
if (obj.ttl >= 0s) {
# Hit within TTL period
return (deliver);
}
if (std.healthy(req.backend_hint)) {
if (obj.ttl + 300s > 0s) {
# Hit after TTL expiration, but within grace period
set req.http.grace = "normal (healthy server)";
return (deliver);
} else {
# Hit after TTL and grace expiration
return (fetch);
}
} else {
# server is not healthy, retrieve from cache
set req.http.grace = "unlimited (unhealthy server)";
return (deliver);
}
}


We've tried almost everything and this should be working but isn't.



Do you guys know anything that can help?



To give you guys an even beter idea of the problem. Here is the entire request header when it successfully caches a page.



accept-language: bytes
age: 215
cache-control: no-store, no-cache, must-revalidate, max-age=0
content-encoding: gzip
content-length: 25669
content-type: text/html; charset=UTF-8
date: Mon, 18 Feb 2019 11:13:00 GMT
expires: -1
pragma: no-cache
status: 200
vary: Accept-Encoding,User-Agent
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-magento-cache-debug: HIT
x-ua-compatible: IE=edge
x-xss-protection: 1; mode=block









share|improve this question







New contributor




Luuk Meijer is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

























    1















    I have a Magento v2.2.6 webshop running and I want Varnish on that. Now I installed Varnish and it seems to be active. But I have a (big) problem.



    How Varnish should work is that it caches pages as soon as one person loads the page/files. The problem I have right now is that the pages are cached again for each person. (the pages are unique to each person/connection)



    So if I load the home page twice on the same device the page is cached. But if I go to the home page on my phone the page needs to be cached again.



    I'm pretty sure that this has something to do with the cookies of the webshop. Since Magento 2 saves everything in one big cookie.
    Also the request headers are:



    cache-control: no-store, no-cache, must-revalidate, max-age=0


    And I don't think it should be like that..



    To give you guys a beter idea, here is the varnish.vcl I'm using right now. It's the default one for Magento 2 except that it always shows a HIT or MISS. (The .host is different but I'm not going post that IP here)



    vcl 4.0;

    import std;
    # The minimal Varnish version is 4.0
    # For SSL offloading, pass the following header in your proxy server or load balancer: 'X-Forwarded-Proto: https'

    backend default {
    .host = "localhost";
    .port = "8080";
    .first_byte_timeout = 600s;
    .probe = {
    .url = "/pub/health_check.php";
    .timeout = 2s;
    .interval = 5s;
    .window = 10;
    .threshold = 5;
    }
    }

    acl purge {
    "localhost";
    }

    sub vcl_recv {
    if (req.method == "PURGE") {
    if (client.ip !~ purge) {
    return (synth(405, "Method not allowed"));
    }
    # To use the X-Pool header for purging varnish during automated deployments, make sure the X-Pool header
    # has been added to the response in your backend server config. This is used, for example, by the
    # capistrano-magento2 gem for purging old content from varnish during it's deploy routine.
    if (!req.http.X-Magento-Tags-Pattern && !req.http.X-Pool) {
    return (synth(400, "X-Magento-Tags-Pattern or X-Pool header required"));
    }
    if (req.http.X-Magento-Tags-Pattern) {
    ban("obj.http.X-Magento-Tags ~ " + req.http.X-Magento-Tags-Pattern);
    }
    if (req.http.X-Pool) {
    ban("obj.http.X-Pool ~ " + req.http.X-Pool);
    }
    return (synth(200, "Purged"));
    }

    if (req.method != "GET" &&
    req.method != "HEAD" &&
    req.method != "PUT" &&
    req.method != "POST" &&
    req.method != "TRACE" &&
    req.method != "OPTIONS" &&
    req.method != "DELETE") {
    /* Non-RFC2616 or CONNECT which is weird. */
    return (pipe);
    }

    # We only deal with GET and HEAD by default
    if (req.method != "GET" && req.method != "HEAD") {
    return (pass);
    }

    # Bypass shopping cart, checkout and search requests
    if (req.url ~ "/checkout" || req.url ~ "/catalogsearch" || req.url ~ "/onestepcheckout" || req.url ~ "/customer") {
    return (pass);
    }

    # Bypass health check requests
    if (req.url ~ "/pub/health_check.php") {
    return (pass);
    }

    # Set initial grace period usage status
    set req.http.grace = "none";

    # normalize url in case of leading HTTP scheme and domain
    set req.url = regsub(req.url, "^http[s]?://", "");

    # collect all cookies
    std.collect(req.http.Cookie);

    # Compression filter. See https://www.varnish-cache.org/trac/wiki/FAQ/Compression
    if (req.http.Accept-Encoding) {
    if (req.url ~ ".(jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf|flv)$") {
    # No point in compressing these
    unset req.http.Accept-Encoding;
    } elsif (req.http.Accept-Encoding ~ "gzip") {
    set req.http.Accept-Encoding = "gzip";
    } elsif (req.http.Accept-Encoding ~ "deflate" && req.http.user-agent !~ "MSIE") {
    set req.http.Accept-Encoding = "deflate";
    } else {
    # unkown algorithm
    unset req.http.Accept-Encoding;
    }
    }

    # Remove Google gclid parameters to minimize the cache objects
    set req.url = regsuball(req.url,"?gclid=[^&]+$",""); # strips when QS = "?gclid=AAA"
    set req.url = regsuball(req.url,"?gclid=[^&]+&","?"); # strips when QS = "?gclid=AAA&foo=bar"
    set req.url = regsuball(req.url,"&gclid=[^&]+",""); # strips when QS = "?foo=bar&gclid=AAA" or QS = "?foo=bar&gclid=AAA&bar=baz"

    # Static files caching
    if (req.url ~ "^/(pub/)?(media|static)/") {
    # Static files should not be cached by default
    # return (pass);

    # But if you use a few locales and don't use CDN you can enable caching static files by commenting previous line (#return (pass);) and uncommenting next 3 lines
    unset req.http.Https;
    unset req.http.X-Forwarded-Proto;
    unset req.http.Cookie;
    }

    return (hash);
    }

    sub vcl_hash {
    if (req.http.cookie ~ "X-Magento-Vary=") {
    hash_data(regsub(req.http.cookie, "^.*?X-Magento-Vary=([^;]+);*.*$", "1"));
    }

    # For multi site configurations to not cache each other's content
    if (req.http.host) {
    hash_data(req.http.host);
    } else {
    hash_data(server.ip);
    }

    # To make sure http users don't see ssl warning
    if (req.http.X-Forwarded-Proto) {
    hash_data(req.http.X-Forwarded-Proto);
    }

    }

    sub vcl_backend_response {

    set beresp.grace = 3d;

    if (beresp.http.content-type ~ "text") {
    set beresp.do_esi = true;
    }

    if (bereq.url ~ ".js$" || beresp.http.content-type ~ "text") {
    set beresp.do_gzip = true;
    }

    if (beresp.http.X-Magento-Debug) {
    set beresp.http.X-Magento-Cache-Control = beresp.http.Cache-Control;
    }

    # cache only successfully responses and 404s
    if (beresp.status != 200 && beresp.status != 404) {
    set beresp.ttl = 0s;
    set beresp.uncacheable = true;
    return (deliver);
    } elsif (beresp.http.Cache-Control ~ "private") {
    set beresp.uncacheable = true;
    set beresp.ttl = 86400s;
    return (deliver);
    }

    # validate if we need to cache it and prevent from setting cookie
    # images, css and js are cacheable by default so we have to remove cookie also
    if (beresp.ttl > 0s && (bereq.method == "GET" || bereq.method == "HEAD")) {
    unset beresp.http.set-cookie;
    }

    # If page is not cacheable then bypass varnish for 2 minutes as Hit-For-Pass
    if (beresp.ttl <= 0s ||
    beresp.http.Surrogate-control ~ "no-store" ||
    (!beresp.http.Surrogate-Control &&
    beresp.http.Cache-Control ~ "no-cache|no-store") ||
    beresp.http.Vary == "*") {
    # Mark as Hit-For-Pass for the next 2 minutes
    set beresp.ttl = 120s;
    set beresp.uncacheable = true;
    }

    return (deliver);
    }

    sub vcl_deliver {
    #if (resp.http.X-Magento-Debug) {
    if (resp.http.x-varnish ~ " ") {
    set resp.http.X-Magento-Cache-Debug = "HIT";
    set resp.http.Grace = req.http.grace;
    } else {
    set resp.http.X-Magento-Cache-Debug = "MISS";
    }
    #} else {
    unset resp.http.Age;
    #}

    # Not letting browser to cache non-static files.
    if (resp.http.Cache-Control !~ "private" && req.url !~ "^/(pub/)?(media|static)/") {
    set resp.http.Pragma = "no-cache";
    set resp.http.Expires = "-1";
    set resp.http.Cache-Control = "no-store, no-cache, must-revalidate, max-age=0";
    }

    unset resp.http.X-Magento-Debug;
    unset resp.http.X-Magento-Tags;
    unset resp.http.X-Powered-By;
    unset resp.http.Server;
    unset resp.http.X-Varnish;
    unset resp.http.Via;
    unset resp.http.Link;
    }

    sub vcl_hit {
    if (obj.ttl >= 0s) {
    # Hit within TTL period
    return (deliver);
    }
    if (std.healthy(req.backend_hint)) {
    if (obj.ttl + 300s > 0s) {
    # Hit after TTL expiration, but within grace period
    set req.http.grace = "normal (healthy server)";
    return (deliver);
    } else {
    # Hit after TTL and grace expiration
    return (fetch);
    }
    } else {
    # server is not healthy, retrieve from cache
    set req.http.grace = "unlimited (unhealthy server)";
    return (deliver);
    }
    }


    We've tried almost everything and this should be working but isn't.



    Do you guys know anything that can help?



    To give you guys an even beter idea of the problem. Here is the entire request header when it successfully caches a page.



    accept-language: bytes
    age: 215
    cache-control: no-store, no-cache, must-revalidate, max-age=0
    content-encoding: gzip
    content-length: 25669
    content-type: text/html; charset=UTF-8
    date: Mon, 18 Feb 2019 11:13:00 GMT
    expires: -1
    pragma: no-cache
    status: 200
    vary: Accept-Encoding,User-Agent
    x-content-type-options: nosniff
    x-frame-options: SAMEORIGIN
    x-magento-cache-debug: HIT
    x-ua-compatible: IE=edge
    x-xss-protection: 1; mode=block









    share|improve this question







    New contributor




    Luuk Meijer is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.























      1












      1








      1








      I have a Magento v2.2.6 webshop running and I want Varnish on that. Now I installed Varnish and it seems to be active. But I have a (big) problem.



      How Varnish should work is that it caches pages as soon as one person loads the page/files. The problem I have right now is that the pages are cached again for each person. (the pages are unique to each person/connection)



      So if I load the home page twice on the same device the page is cached. But if I go to the home page on my phone the page needs to be cached again.



      I'm pretty sure that this has something to do with the cookies of the webshop. Since Magento 2 saves everything in one big cookie.
      Also the request headers are:



      cache-control: no-store, no-cache, must-revalidate, max-age=0


      And I don't think it should be like that..



      To give you guys a beter idea, here is the varnish.vcl I'm using right now. It's the default one for Magento 2 except that it always shows a HIT or MISS. (The .host is different but I'm not going post that IP here)



      vcl 4.0;

      import std;
      # The minimal Varnish version is 4.0
      # For SSL offloading, pass the following header in your proxy server or load balancer: 'X-Forwarded-Proto: https'

      backend default {
      .host = "localhost";
      .port = "8080";
      .first_byte_timeout = 600s;
      .probe = {
      .url = "/pub/health_check.php";
      .timeout = 2s;
      .interval = 5s;
      .window = 10;
      .threshold = 5;
      }
      }

      acl purge {
      "localhost";
      }

      sub vcl_recv {
      if (req.method == "PURGE") {
      if (client.ip !~ purge) {
      return (synth(405, "Method not allowed"));
      }
      # To use the X-Pool header for purging varnish during automated deployments, make sure the X-Pool header
      # has been added to the response in your backend server config. This is used, for example, by the
      # capistrano-magento2 gem for purging old content from varnish during it's deploy routine.
      if (!req.http.X-Magento-Tags-Pattern && !req.http.X-Pool) {
      return (synth(400, "X-Magento-Tags-Pattern or X-Pool header required"));
      }
      if (req.http.X-Magento-Tags-Pattern) {
      ban("obj.http.X-Magento-Tags ~ " + req.http.X-Magento-Tags-Pattern);
      }
      if (req.http.X-Pool) {
      ban("obj.http.X-Pool ~ " + req.http.X-Pool);
      }
      return (synth(200, "Purged"));
      }

      if (req.method != "GET" &&
      req.method != "HEAD" &&
      req.method != "PUT" &&
      req.method != "POST" &&
      req.method != "TRACE" &&
      req.method != "OPTIONS" &&
      req.method != "DELETE") {
      /* Non-RFC2616 or CONNECT which is weird. */
      return (pipe);
      }

      # We only deal with GET and HEAD by default
      if (req.method != "GET" && req.method != "HEAD") {
      return (pass);
      }

      # Bypass shopping cart, checkout and search requests
      if (req.url ~ "/checkout" || req.url ~ "/catalogsearch" || req.url ~ "/onestepcheckout" || req.url ~ "/customer") {
      return (pass);
      }

      # Bypass health check requests
      if (req.url ~ "/pub/health_check.php") {
      return (pass);
      }

      # Set initial grace period usage status
      set req.http.grace = "none";

      # normalize url in case of leading HTTP scheme and domain
      set req.url = regsub(req.url, "^http[s]?://", "");

      # collect all cookies
      std.collect(req.http.Cookie);

      # Compression filter. See https://www.varnish-cache.org/trac/wiki/FAQ/Compression
      if (req.http.Accept-Encoding) {
      if (req.url ~ ".(jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf|flv)$") {
      # No point in compressing these
      unset req.http.Accept-Encoding;
      } elsif (req.http.Accept-Encoding ~ "gzip") {
      set req.http.Accept-Encoding = "gzip";
      } elsif (req.http.Accept-Encoding ~ "deflate" && req.http.user-agent !~ "MSIE") {
      set req.http.Accept-Encoding = "deflate";
      } else {
      # unkown algorithm
      unset req.http.Accept-Encoding;
      }
      }

      # Remove Google gclid parameters to minimize the cache objects
      set req.url = regsuball(req.url,"?gclid=[^&]+$",""); # strips when QS = "?gclid=AAA"
      set req.url = regsuball(req.url,"?gclid=[^&]+&","?"); # strips when QS = "?gclid=AAA&foo=bar"
      set req.url = regsuball(req.url,"&gclid=[^&]+",""); # strips when QS = "?foo=bar&gclid=AAA" or QS = "?foo=bar&gclid=AAA&bar=baz"

      # Static files caching
      if (req.url ~ "^/(pub/)?(media|static)/") {
      # Static files should not be cached by default
      # return (pass);

      # But if you use a few locales and don't use CDN you can enable caching static files by commenting previous line (#return (pass);) and uncommenting next 3 lines
      unset req.http.Https;
      unset req.http.X-Forwarded-Proto;
      unset req.http.Cookie;
      }

      return (hash);
      }

      sub vcl_hash {
      if (req.http.cookie ~ "X-Magento-Vary=") {
      hash_data(regsub(req.http.cookie, "^.*?X-Magento-Vary=([^;]+);*.*$", "1"));
      }

      # For multi site configurations to not cache each other's content
      if (req.http.host) {
      hash_data(req.http.host);
      } else {
      hash_data(server.ip);
      }

      # To make sure http users don't see ssl warning
      if (req.http.X-Forwarded-Proto) {
      hash_data(req.http.X-Forwarded-Proto);
      }

      }

      sub vcl_backend_response {

      set beresp.grace = 3d;

      if (beresp.http.content-type ~ "text") {
      set beresp.do_esi = true;
      }

      if (bereq.url ~ ".js$" || beresp.http.content-type ~ "text") {
      set beresp.do_gzip = true;
      }

      if (beresp.http.X-Magento-Debug) {
      set beresp.http.X-Magento-Cache-Control = beresp.http.Cache-Control;
      }

      # cache only successfully responses and 404s
      if (beresp.status != 200 && beresp.status != 404) {
      set beresp.ttl = 0s;
      set beresp.uncacheable = true;
      return (deliver);
      } elsif (beresp.http.Cache-Control ~ "private") {
      set beresp.uncacheable = true;
      set beresp.ttl = 86400s;
      return (deliver);
      }

      # validate if we need to cache it and prevent from setting cookie
      # images, css and js are cacheable by default so we have to remove cookie also
      if (beresp.ttl > 0s && (bereq.method == "GET" || bereq.method == "HEAD")) {
      unset beresp.http.set-cookie;
      }

      # If page is not cacheable then bypass varnish for 2 minutes as Hit-For-Pass
      if (beresp.ttl <= 0s ||
      beresp.http.Surrogate-control ~ "no-store" ||
      (!beresp.http.Surrogate-Control &&
      beresp.http.Cache-Control ~ "no-cache|no-store") ||
      beresp.http.Vary == "*") {
      # Mark as Hit-For-Pass for the next 2 minutes
      set beresp.ttl = 120s;
      set beresp.uncacheable = true;
      }

      return (deliver);
      }

      sub vcl_deliver {
      #if (resp.http.X-Magento-Debug) {
      if (resp.http.x-varnish ~ " ") {
      set resp.http.X-Magento-Cache-Debug = "HIT";
      set resp.http.Grace = req.http.grace;
      } else {
      set resp.http.X-Magento-Cache-Debug = "MISS";
      }
      #} else {
      unset resp.http.Age;
      #}

      # Not letting browser to cache non-static files.
      if (resp.http.Cache-Control !~ "private" && req.url !~ "^/(pub/)?(media|static)/") {
      set resp.http.Pragma = "no-cache";
      set resp.http.Expires = "-1";
      set resp.http.Cache-Control = "no-store, no-cache, must-revalidate, max-age=0";
      }

      unset resp.http.X-Magento-Debug;
      unset resp.http.X-Magento-Tags;
      unset resp.http.X-Powered-By;
      unset resp.http.Server;
      unset resp.http.X-Varnish;
      unset resp.http.Via;
      unset resp.http.Link;
      }

      sub vcl_hit {
      if (obj.ttl >= 0s) {
      # Hit within TTL period
      return (deliver);
      }
      if (std.healthy(req.backend_hint)) {
      if (obj.ttl + 300s > 0s) {
      # Hit after TTL expiration, but within grace period
      set req.http.grace = "normal (healthy server)";
      return (deliver);
      } else {
      # Hit after TTL and grace expiration
      return (fetch);
      }
      } else {
      # server is not healthy, retrieve from cache
      set req.http.grace = "unlimited (unhealthy server)";
      return (deliver);
      }
      }


      We've tried almost everything and this should be working but isn't.



      Do you guys know anything that can help?



      To give you guys an even beter idea of the problem. Here is the entire request header when it successfully caches a page.



      accept-language: bytes
      age: 215
      cache-control: no-store, no-cache, must-revalidate, max-age=0
      content-encoding: gzip
      content-length: 25669
      content-type: text/html; charset=UTF-8
      date: Mon, 18 Feb 2019 11:13:00 GMT
      expires: -1
      pragma: no-cache
      status: 200
      vary: Accept-Encoding,User-Agent
      x-content-type-options: nosniff
      x-frame-options: SAMEORIGIN
      x-magento-cache-debug: HIT
      x-ua-compatible: IE=edge
      x-xss-protection: 1; mode=block









      share|improve this question







      New contributor




      Luuk Meijer is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.












      I have a Magento v2.2.6 webshop running and I want Varnish on that. Now I installed Varnish and it seems to be active. But I have a (big) problem.



      How Varnish should work is that it caches pages as soon as one person loads the page/files. The problem I have right now is that the pages are cached again for each person. (the pages are unique to each person/connection)



      So if I load the home page twice on the same device the page is cached. But if I go to the home page on my phone the page needs to be cached again.



      I'm pretty sure that this has something to do with the cookies of the webshop. Since Magento 2 saves everything in one big cookie.
      Also the request headers are:



      cache-control: no-store, no-cache, must-revalidate, max-age=0


      And I don't think it should be like that..



      To give you guys a beter idea, here is the varnish.vcl I'm using right now. It's the default one for Magento 2 except that it always shows a HIT or MISS. (The .host is different but I'm not going post that IP here)



      vcl 4.0;

      import std;
      # The minimal Varnish version is 4.0
      # For SSL offloading, pass the following header in your proxy server or load balancer: 'X-Forwarded-Proto: https'

      backend default {
      .host = "localhost";
      .port = "8080";
      .first_byte_timeout = 600s;
      .probe = {
      .url = "/pub/health_check.php";
      .timeout = 2s;
      .interval = 5s;
      .window = 10;
      .threshold = 5;
      }
      }

      acl purge {
      "localhost";
      }

      sub vcl_recv {
      if (req.method == "PURGE") {
      if (client.ip !~ purge) {
      return (synth(405, "Method not allowed"));
      }
      # To use the X-Pool header for purging varnish during automated deployments, make sure the X-Pool header
      # has been added to the response in your backend server config. This is used, for example, by the
      # capistrano-magento2 gem for purging old content from varnish during it's deploy routine.
      if (!req.http.X-Magento-Tags-Pattern && !req.http.X-Pool) {
      return (synth(400, "X-Magento-Tags-Pattern or X-Pool header required"));
      }
      if (req.http.X-Magento-Tags-Pattern) {
      ban("obj.http.X-Magento-Tags ~ " + req.http.X-Magento-Tags-Pattern);
      }
      if (req.http.X-Pool) {
      ban("obj.http.X-Pool ~ " + req.http.X-Pool);
      }
      return (synth(200, "Purged"));
      }

      if (req.method != "GET" &&
      req.method != "HEAD" &&
      req.method != "PUT" &&
      req.method != "POST" &&
      req.method != "TRACE" &&
      req.method != "OPTIONS" &&
      req.method != "DELETE") {
      /* Non-RFC2616 or CONNECT which is weird. */
      return (pipe);
      }

      # We only deal with GET and HEAD by default
      if (req.method != "GET" && req.method != "HEAD") {
      return (pass);
      }

      # Bypass shopping cart, checkout and search requests
      if (req.url ~ "/checkout" || req.url ~ "/catalogsearch" || req.url ~ "/onestepcheckout" || req.url ~ "/customer") {
      return (pass);
      }

      # Bypass health check requests
      if (req.url ~ "/pub/health_check.php") {
      return (pass);
      }

      # Set initial grace period usage status
      set req.http.grace = "none";

      # normalize url in case of leading HTTP scheme and domain
      set req.url = regsub(req.url, "^http[s]?://", "");

      # collect all cookies
      std.collect(req.http.Cookie);

      # Compression filter. See https://www.varnish-cache.org/trac/wiki/FAQ/Compression
      if (req.http.Accept-Encoding) {
      if (req.url ~ ".(jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf|flv)$") {
      # No point in compressing these
      unset req.http.Accept-Encoding;
      } elsif (req.http.Accept-Encoding ~ "gzip") {
      set req.http.Accept-Encoding = "gzip";
      } elsif (req.http.Accept-Encoding ~ "deflate" && req.http.user-agent !~ "MSIE") {
      set req.http.Accept-Encoding = "deflate";
      } else {
      # unkown algorithm
      unset req.http.Accept-Encoding;
      }
      }

      # Remove Google gclid parameters to minimize the cache objects
      set req.url = regsuball(req.url,"?gclid=[^&]+$",""); # strips when QS = "?gclid=AAA"
      set req.url = regsuball(req.url,"?gclid=[^&]+&","?"); # strips when QS = "?gclid=AAA&foo=bar"
      set req.url = regsuball(req.url,"&gclid=[^&]+",""); # strips when QS = "?foo=bar&gclid=AAA" or QS = "?foo=bar&gclid=AAA&bar=baz"

      # Static files caching
      if (req.url ~ "^/(pub/)?(media|static)/") {
      # Static files should not be cached by default
      # return (pass);

      # But if you use a few locales and don't use CDN you can enable caching static files by commenting previous line (#return (pass);) and uncommenting next 3 lines
      unset req.http.Https;
      unset req.http.X-Forwarded-Proto;
      unset req.http.Cookie;
      }

      return (hash);
      }

      sub vcl_hash {
      if (req.http.cookie ~ "X-Magento-Vary=") {
      hash_data(regsub(req.http.cookie, "^.*?X-Magento-Vary=([^;]+);*.*$", "1"));
      }

      # For multi site configurations to not cache each other's content
      if (req.http.host) {
      hash_data(req.http.host);
      } else {
      hash_data(server.ip);
      }

      # To make sure http users don't see ssl warning
      if (req.http.X-Forwarded-Proto) {
      hash_data(req.http.X-Forwarded-Proto);
      }

      }

      sub vcl_backend_response {

      set beresp.grace = 3d;

      if (beresp.http.content-type ~ "text") {
      set beresp.do_esi = true;
      }

      if (bereq.url ~ ".js$" || beresp.http.content-type ~ "text") {
      set beresp.do_gzip = true;
      }

      if (beresp.http.X-Magento-Debug) {
      set beresp.http.X-Magento-Cache-Control = beresp.http.Cache-Control;
      }

      # cache only successfully responses and 404s
      if (beresp.status != 200 && beresp.status != 404) {
      set beresp.ttl = 0s;
      set beresp.uncacheable = true;
      return (deliver);
      } elsif (beresp.http.Cache-Control ~ "private") {
      set beresp.uncacheable = true;
      set beresp.ttl = 86400s;
      return (deliver);
      }

      # validate if we need to cache it and prevent from setting cookie
      # images, css and js are cacheable by default so we have to remove cookie also
      if (beresp.ttl > 0s && (bereq.method == "GET" || bereq.method == "HEAD")) {
      unset beresp.http.set-cookie;
      }

      # If page is not cacheable then bypass varnish for 2 minutes as Hit-For-Pass
      if (beresp.ttl <= 0s ||
      beresp.http.Surrogate-control ~ "no-store" ||
      (!beresp.http.Surrogate-Control &&
      beresp.http.Cache-Control ~ "no-cache|no-store") ||
      beresp.http.Vary == "*") {
      # Mark as Hit-For-Pass for the next 2 minutes
      set beresp.ttl = 120s;
      set beresp.uncacheable = true;
      }

      return (deliver);
      }

      sub vcl_deliver {
      #if (resp.http.X-Magento-Debug) {
      if (resp.http.x-varnish ~ " ") {
      set resp.http.X-Magento-Cache-Debug = "HIT";
      set resp.http.Grace = req.http.grace;
      } else {
      set resp.http.X-Magento-Cache-Debug = "MISS";
      }
      #} else {
      unset resp.http.Age;
      #}

      # Not letting browser to cache non-static files.
      if (resp.http.Cache-Control !~ "private" && req.url !~ "^/(pub/)?(media|static)/") {
      set resp.http.Pragma = "no-cache";
      set resp.http.Expires = "-1";
      set resp.http.Cache-Control = "no-store, no-cache, must-revalidate, max-age=0";
      }

      unset resp.http.X-Magento-Debug;
      unset resp.http.X-Magento-Tags;
      unset resp.http.X-Powered-By;
      unset resp.http.Server;
      unset resp.http.X-Varnish;
      unset resp.http.Via;
      unset resp.http.Link;
      }

      sub vcl_hit {
      if (obj.ttl >= 0s) {
      # Hit within TTL period
      return (deliver);
      }
      if (std.healthy(req.backend_hint)) {
      if (obj.ttl + 300s > 0s) {
      # Hit after TTL expiration, but within grace period
      set req.http.grace = "normal (healthy server)";
      return (deliver);
      } else {
      # Hit after TTL and grace expiration
      return (fetch);
      }
      } else {
      # server is not healthy, retrieve from cache
      set req.http.grace = "unlimited (unhealthy server)";
      return (deliver);
      }
      }


      We've tried almost everything and this should be working but isn't.



      Do you guys know anything that can help?



      To give you guys an even beter idea of the problem. Here is the entire request header when it successfully caches a page.



      accept-language: bytes
      age: 215
      cache-control: no-store, no-cache, must-revalidate, max-age=0
      content-encoding: gzip
      content-length: 25669
      content-type: text/html; charset=UTF-8
      date: Mon, 18 Feb 2019 11:13:00 GMT
      expires: -1
      pragma: no-cache
      status: 200
      vary: Accept-Encoding,User-Agent
      x-content-type-options: nosniff
      x-frame-options: SAMEORIGIN
      x-magento-cache-debug: HIT
      x-ua-compatible: IE=edge
      x-xss-protection: 1; mode=block






      magento2 varnish






      share|improve this question







      New contributor




      Luuk Meijer is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question







      New contributor




      Luuk Meijer is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question






      New contributor




      Luuk Meijer is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 14 hours ago









      Luuk MeijerLuuk Meijer

      61




      61




      New contributor




      Luuk Meijer is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      Luuk Meijer is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      Luuk Meijer is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






















          0






          active

          oldest

          votes











          Your Answer








          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "479"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });






          Luuk Meijer is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmagento.stackexchange.com%2fquestions%2f262246%2fmagento-2-varnish-caching-per-instance%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          Luuk Meijer is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          Luuk Meijer is a new contributor. Be nice, and check out our Code of Conduct.













          Luuk Meijer is a new contributor. Be nice, and check out our Code of Conduct.












          Luuk Meijer is a new contributor. Be nice, and check out our Code of Conduct.
















          Thanks for contributing an answer to Magento Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmagento.stackexchange.com%2fquestions%2f262246%2fmagento-2-varnish-caching-per-instance%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Polycentropodidae

          Magento 2 Error message: Invalid state change requested

          Paulmy