Cache purge using nginx helper for sites behind Cloudflare

Consider a WordPress site in running on a Lemp stack, taking advantage of fast-cgi cache and using the excelent Nginx helper plugin to conditionaly purge the cache. The site is also behind Cloudflare and takes advantage of Cloudflare flexible SSL encryprtion.

The cache key needed by the Nginx helper is

$schema$request_method$host$request_uri

You notice, that the cache is not automatically purged as it should be. Everything else is working fine, pages are cached and if you purge the entire cache, they are properly invalidated.

The problem is the $schema part of the cache key. Since the flexible encryption is enabled, the encryption takes place only between the client and Cloudflare, while the connection between Cloudflare and nginx is unencrypted and as far as nginx is concerned, the schema is http.

Nginx helper on the other hand gets the url to purge from PATH_INFO which is client provided, and claims the schema is as the client sees it https. Nginx helper thus calculates his cache key using the wrong schema and tries to delete a file that does not exist.

The solution

The only solution I have found to this problem is mapping the X-Forwarded-Proto to the $scheme variable.

In nginx configuration /etc/nginx/conf.d create a file maps.conf with the following content:

map $http_x_forwarded_proto $cf_proto {
        default $scheme;
        https https;
}

This means: if the $http_x_forwarded_proto exists and is set to http, set $cf_proto to https, else set it to the value of the $scheme variable.

You shouid include this variable in nginx.conf before including virtual host configs with the line

include maps.conf;

Then open the file /etc/nginx/conf.d/fastcfgi.conf and change the fastcgi_cache_key to

fastcgi_cache_key "$cf_proto$request_method$host$request_uri";

Finally check if you have no syntax error in config files and reload nginx configurations

# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# /etc/init.d/nginx reload
[ ok ] Reloading nginx configuration (via systemctl): nginx.service.

Nginx helper will now be able to always clear the cache of an edited post or page.