1

I have a magento 2.1 with a apache and varnish 4 installed on a Centos 7. (apache running in port number 8080 and varnish in port number 80 in the same server. The server's external IP address is: 79.175.173.210)

The problem is that 'Flushing Magento Cache' in admin panel won't actually flush full-page-cache.

I have used sudo varnishlog -g request -q 'ReqMethod eq "PURGE"' to view the varnish purge log. It will generate a purge request toward the varnish, but it would get a Method not allowed error message. After "Flushing" magento cache, it would produce the following output:

*   << Request  >> 98310
-   Begin          req 98309 rxreq
-   Timestamp      Start: 1499706749.687418 0.000000 0.000000
-   Timestamp      Req: 1499706749.687418 0.000000 0.000000
-   ReqStart       79.175.173.210 39958
-   ReqMethod      PURGE
-   ReqURL         /
-   ReqProtocol    HTTP/1.1
-   ReqHeader      X-Magento-Tags-Pattern: .*
-   ReqHeader      X-Forwarded-For: 79.175.173.210
-   VCL_call       RECV
-   VCL_acl        NO_MATCH purge
-   Debug          "VCL_error(405, Method not allowed)"
-   VCL_return     synth
-   VCL_call       HASH
-   VCL_return     lookup
-   Timestamp      Process: 1499706749.687465 0.000047 0.000047
-   RespHeader     Date: Mon, 10 Jul 2017 17:12:29 GMT
-   RespHeader     Server: Varnish
-   RespHeader     X-Varnish: 98310
-   RespProtocol   HTTP/1.1
-   RespStatus     405
-   RespReason     Method Not Allowed
-   RespReason     Method not allowed
-   VCL_call       SYNTH
-   RespHeader     Content-Type: text/html; charset=utf-8
-   RespHeader     Retry-After: 5
-   VCL_return     deliver
-   RespHeader     Content-Length: 276
-   Debug          "RES_MODE 2"
-   RespHeader     Connection: keep-alive
-   Timestamp      Resp: 1499706749.687575 0.000158 0.000110
-   ReqAcct        48 0 48 208 276 484
-   End

The varnish config file is followed:

/etc/varnish/varnish.vcl

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 = "127.0.0.1";
    .port = "8080";
}

acl purge {
    "127.0.0.1";
    "localhost";
    "79.175.173.210";
}

sub vcl_recv {
    if (req.method == "PURGE") {
        if (client.ip !~ purge) {
            return (synth(405, "Method not allowed"));
        }
        if (!req.http.X-Magento-Tags-Pattern) {
            return (synth(400, "X-Magento-Tags-Pattern header required"));
        }
        ban("obj.http.X-Magento-Tags ~ " + req.http.X-Magento-Tags-Pattern);
        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") {
        return (pass);
    }

    # 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 are always cacheable. remove SSL flag and cookie
        if (req.url ~ "^/(pub/)?(media|static)/.*\.(ico|css|js|jpg|jpeg|png|gif|tiff|bmp|mp3|ogg|svg|swf|woff|woff2|eot|ttf|otf)$") {
        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 {
    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;
    }

    # 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);
    }

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

    # 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 (bereq.url !~ "\.(ico|css|js|jpg|jpeg|png|gif|tiff|bmp|gz|tgz|bz2|tbz|mp3|ogg|svg|swf|woff|woff2|eot|ttf|otf)(\?|$)") {
            set beresp.http.Pragma = "no-cache";
            set beresp.http.Expires = "-1";
            set beresp.http.Cache-Control = "no-store, no-cache, must-revalidate, max-age=0";
            set beresp.grace = 1m;
        }
    }

   # 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.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";
        } else {
            set resp.http.X-Magento-Cache-Debug = "MISS";
        }
    } else {
        unset resp.http.Age;
    }

    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;
}
2
  • Perhaps you have not reloaded your Varnish config. Everything looks fine, but it won't match the IP which you have already added to acl. Jul 10, 2017 at 19:40
  • Thanks for your help. I have ran sudo service varnish restart. Also have rebooted the system to keep safe! But the error above keeps appearing! Jul 11, 2017 at 1:35

2 Answers 2

7

Are you sure you have added the varnish cache to the Magento env.php config? You can do this by manually editing env.php or with this command

php bin/magento setup:config:set --http-cache-hosts=hostname

Until you do this Varnish will cache but clearing caches in Magento admin will not purge the Varnish cache.

6
  • Thanks paj! the php bin/magento setup:config:set --http-cache-hosts=127.0.0.1 was all needed. Jul 11, 2017 at 1:53
  • It's described here devdocs.magento.com/guides/v2.0/config-guide/varnish/…
    – Gediminas
    Jul 11, 2017 at 7:07
  • @Gediminas thanks for the info. I should have missed the document! Jul 11, 2017 at 18:14
  • @Pro-Magento it's tricky page, because looks like additional information but is important.
    – Gediminas
    Jul 13, 2017 at 10:17
  • 1
    Further hint: if you define acl purge { "127.0.0.1" } you have to setup http-cache-hosts with this IP and not with "localhost". Is has to be the same as it seems.
    – robsch
    Jun 29, 2020 at 8:52
0

If you use multiple domains in one varnish instance make sure that http-cache-hosts has exact same value as req.http.host == "your.domain2" in vcl

env.php

    'http_cache_hosts' => [
        [
            'host' => 'your.domain2',
            'port' => '6081'
        ]
    ],

root.vcl

sub vcl_recv {
    if (req.http.host == "your.domain") {
        return (vcl(label-domain));
    } else if (req.http.host == "your.domain2") {
        return (vcl(label-domain2));
    } else {
        return (synth(404));
    }   
}

domain2.vcl

acl purge {
    "your.domain2";
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.