Home > Software engineering >  Docker / Varnish / Hitch / Nginx / PHP : What is correct way to purge cache for specific page?
Docker / Varnish / Hitch / Nginx / PHP : What is correct way to purge cache for specific page?

Time:01-19

I have setup simple php app via docker by using hitch, varnish, nginx, php and mysql containers. To make Hitch work locally I've generated self-signed certificate via mkcert utility for my.varnish.test local domain that was added to /etc/hosts

So https://my.varnish.test works fine locally.

Here is github of the app: https://github.com/aposidelov/hitch-varnish-local-example

The app does following:

  • Listing page (/index.php) where all rows from mysql table are shown.
  • Add form (/user_add_form.php) that allows to add new row to mysql table.

I want Listing page to be cached via varnish and after Add form is submitted I want Listing page to be purged. For now /index.php is cached by varnish but I have problems how to purge specific page after form is submitted.

What is correct way to purge a cache?

I've found approach by doing it using curl call with PURGE method.

exec('curl -I -X PURGE https://my.varnish.test/index.php', $output, $retval);

But as I use docker in my project it means that https://my.varnish.test is not available from nginx container (at least on my local machine). If I go inside my nginx container and try curl https://my.varnish.test/index.php it doesn't see it, instead it's can see only curl http://nginx_server/index.php but purge via exec('curl -I -X PURGE http://nginx_server/index.php', $output, $retval); doesn't work.

CodePudding user response:

Your Git repo has a default.vcl that has the necessary code in it to perform the purge.

However, the purge logic will not be reached because an earlier if-statement will result in an early exit.

Consider this code that is in your Git repo:

sub vcl_recv {
  if (req.method != "GET" && req.method != "HEAD") {
    return (pass);
  }
  if (req.method == "PURGE") {
    if (!client.ip ~ purge) {
      return (synth(405, client.ip   " is not allowed to send PURGE requests."));
    }
    return (purge);
  }
}

The PURGE request method will match the first if-statement (not a GET and not a HEAD) and will result in return(pass); being called.

Please put this if-statement after your purge logic and you'll be able to perform purges.

Another hurdle might be the ACL that is restricted to local IP addresses as you can see in the example below:

acl purge {
  "localhost";
  "127.0.0.1";
  "::1";
}

My advice is to look at the topology of your Docker setup and potentially add the IP address of the system that will execute the PURGE request. This could be an IP addressed issued by Docker.

  • Related