Recientemente hemos hablado sobre como configurar Ghost con Varnish para acelerar la carga de contenido. Si bien es cierto que para limpiar la cache de Varnish es necesario reiniciar el servicio y se pueden hacer varias cosas para automatizar este proceso, hoy os vamos a explicar como reiniciar la cache utilizando un webhook de Ghost.

Si aún no tienes configurado Ghost con Varnish, aquí te dejamos el artículo con toda la información:

Acelera Ghost CMS con Varnish Cache
Pero aquí hemos venido a mejorar el rendimiento de nuestra web. Así que lo que haremos será añadir una capa entre Nginx y Ghost para que Varnish almacene en caché el contenido estático en la RAM y que sólo pase las peticiones de contenido que no se almacenen en cache.

Purgar automáticamente la cache de Varnish

Lo que haremos es eliminar la cache cuando por ejemplo, publiquemos un artículo nuevo en Ghost. De esta manera, nuestros lectores tendrán una versión reciente de la web.

💡
Para la mayoría de los cachés, la gente usa "purgar" como término para referirse a eliminar todo el caché o eliminar un objeto en particular. Para Varnish, PURGE se refiere a eliminar un objeto y BAN se refiere a eliminar parte o todo el contenido. Lo que usaremos es BAN, porque Ghost no tiene la granularidad para PURGE más específicamente.

La forma en que Varnish documenta esto es utilizando el método BAN en lugar del método GET. Por ejemplo, podemos agregar el siguiente código en el fichero de configuración de Varnish. Lo haremos añadiendo una ACL (lista de control de acceso) para que solo se aplique a las IP que indiquemos en ese listado.

💡
Como que estamos usando Ghost en localhost y Varnish está escuchando solo a esa IP (127.0.0.1) solo tendremos que purgar la cache para esa IP.
acl purge {
    "127.0.0.1";
}

sub vcl_recv {
  if (req.method == "BAN") {
    if (!client.ip ~ purge) {
      return(synth(403, "Not allowed."));
    }
    if (std.ban("req.http.host == " + req.http.host + " && req.url == " + req.url)) {
      return(synth(200, "Ban added"));
    } else {
      return(synth(400, std.ban_error()));
    }
  }
}

Esto nos puede ser útil, pero nosotros queremos que la caché se limpie cuando publiquemos un artículo. Para ello, deberemos de crear un webhook en nuestro Ghost y configurar Varnish como se explica a continuación.

Crear un webhook

Para limpiar la cache usando el webhook, deberemos de añadir lo siguiente en /etc/varnish/default.vcl, primero el ACL:

acl purge {
  "127.0.0.1";
}

Y luego añadimos el siguiente bloque de código (por encima del bloque de código para el anterior vcl_recv añadido en el tutorial anterior):

sub vcl_recv {
  if (req.url ~ "/rebuild/purge") {
  
    if (!client.ip ~ purge) {
      return(synth(403, "Not allowed."));
    }
    ban("req.http.host == [TU_DOMINIO]");
    return(synth(200, "Caché limpiada correctamente!"));
  }
}
🚨
Recuerda de cambiar [TU_DOMINIO] por el dominio de tu Ghost.

Tras este cambio, reiniciamos el servicio para que se apliquen los cambios:

systemctl restart varnish

Comprobaciones de la cache

Si ahora hacemos un curl y probamos de descargar contenido de nuestro Ghost, veremos lo siguiente:

# curl -v https://tutos.top/content/images/size/w1000/2023/09/Screenshot_20230807_231808-1.png  2>&1 | grep "Age:"
< Age: 23

Si ahora purgamos la cache de Varnish usando la configuración anterior:

# curl http://127.0.0.1:6081/rebuild/purge
<!DOCTYPE html>
<html>
  <head>
    <title>200 Cache cleared</title>
  </head>
  <body>
    <h1>Error 200 Cache cleared</h1>
    <p>Caché limpiada correctamente!</p>
    <h3>Guru Meditation:</h3>
    <p>XID: 32782</p>
    <hr>
    <p>Varnish cache server</p>
  </body>
</html>

Y si volvemos a ejecutar el curl anterior para ver la edad de la imagen:

# curl -v https://tutos.top/content/images/size/w1000/2023/09/Screenshot_20230807_231808-1.png  2>&1 | grep "Age:"
< Age: 0

Observa que vemos que la respuesta indica "Caché limpiada correctamente!" que establecimos en el archivo, y la edad de nuestro fichero ha vuelto a 0. ¡Funciona!

Creando webhook en Ghost

Para crear el webhook iremos al apartado de Settings de Ghost y luego en Advanced iremos al apartado Integrations.

Haremos clic sobre el botón de abajo que indica Add custom integration y le pondremos un nombre:

Y crearemos un nuevo webhook haciendo clic en + Add webhook:

Añadiremos un nombre, el evento y la URL como se indica en la siguiente captura:

Ahora podemos probar si Ghost activa el webhook cuando queremos y si borra la cache como habíamos planeado. Si editamos o creamos un post, cuando guardemos los cambios, si volvemos a la lista de integraciones veremos que en el apartado Last Triggered añadirá la fecha y hora de la última vez que se activó.

¡Genial! Ahora Varnish está guardando la caché de las partes del sitio que le hemos indicado, y Ghost está controlando cuándo se purga esa caché.