Open kigajewex opened 5 years ago
wow great work haha i used your code as inspiration to create a new one on python to clean slice caches :)
I'll piggy-back on this post, hopefully it catches the attention of more people and they can be saved the 2-3 hours of time I invested in trying to figure out this whole mess.
First of all, if you are a Debian or Ubuntu (or derivatives) user, know that YES this is the github repository of the module packaged as libnginx-mod-http-cache-purge
in your distribution. This module is also in use if you use Ondřej Surý's PPA.
When I set up on the path of fastcgi_cache
, and after I scoured the internet, I was obviously interested in a way to PURGE
the cache of fastcgi
.
Amongst the first few articles I found (and that you will probably find, too), are all mentioning about fasctcgi_cache_purge
.
Sadly, as you dwelve deeper, you will find that fastcgi_cache_purge
is only part of the subscription-model NGINX Plus, which I'm sure it's a great product, but I've learned the lesson that if you have to ask for what the price of a product is (they are not displaying it anywhere public), it's too expensive.
Luckily, you can see that there are quite a few 3rd party modules for nginx that mention cache purging and fastcgi.
This is one of them. Or, I should say, this was one of them.
I've attempted all the possible configuration variants to get this to work, but alas, to no avail.
So to save you some time: DO NOT USE THIS MODULE, IT DOES NOT WORK
fastcgi_cache_path /var/cache/nginx/ levels=1:2 keys_zone=App:100m;
fastcgi_cache_key "$request_method$host$request_uri";
server {
listen 80;
add_header X-Cache $upstream_cache_status;
# your other config variables
location ~ .\php {
# all your fastcgi params
fastcgi_cache_valid 200 1 d;
fastcgi_cache App;
}
location ~ /purge(/.*) {
# $1 is the part of the URL after /purge, and we are using that instead
# $request_uri would otherwise start with /purge and our KEYs would not match
fastcgi_cache_purge App "$request_method$host$1";
return 200 "PURGED: $request_method$host$1";
}
}
Explanation: we are using $request_method$host$request_uri
as a KEY for caching, because we want to cache HEAD
and GET
requests separately. If you do not use $request_method
in your KEY, you will sometimes get empty results from the cache. This is because when someone does a HEAD /uri
, nginx returns to body (because it was obviously asked to return only the HEADers), thus if someone does a HEAD
before a GET
versus the same URI, the empty HEAD
will be cached.
So in order to trigger this, we should simply be able to append the $request_uri
to /purge/
and it should clear, per fastcgi_cache_purge
.
# first check for the cache status:
$ curl -I http://app/example.php
HTTP/2 200
server: nginx/1.16.1
[...]
x-cache: HIT
# then send the request to /purge/:
$ curl http://app/purge/example.php
PURGED: GETapp/example
This will do absolutely nothing.
Obviously, you can not use PURGE
when you are using $request_method
as a KEY, because the KEY will not match when purging.
$request_method
)To use the PURGE
method, you will have to alter your KEY to something like $host$request_uri
, but that will lead to the problem I mentioned above, about caching and serving blank pages if someone does a HEAD
on your URI.
Nevertheless, I have tested this, too.
Config like above, but:
fastcgi_cache_key "$host$request_uri";
server {
# ...
error_page 405 $request_uri; # to keep it from throwing a 405 method not allowed
location ~ .\php {
# same as above, just add:
fastcgi_cache_purge PURGE from all;
}
# remove the /purge location block
}
This should be as easy as:
$ curl -X PURGE http://app/example.php
Yet... nothing happens. The cache stays on the disk, the same file is served.
server{}
block and "separate location"This is the example from https://groups.drupal.org/node/125094
We remove any reference about fastcgi_cache_purge
from our main server{}
block, and we add another one that listens on a different port and it's only purpose is to serve as an endpoint for cache clearing
server {
listen 9898;
error_page 405 $request_uri;
location / {
fastcgi_cache_purge App "$host$request_uri";
return 200 "Purged: $host$request_uri";
}
}
In theory, this should do fastcgi_cache_purge
for our App
's $host$request_uri
, regardless of method we use to access this, so either one of these should work:
$ curl http://app:9898
Purged: app/
$ curl -X PURGE http://app:9898
Purged: app/
Yet, again, nothing actually happens. Cached file is still served.
You should not use "return" in the test I believe because it is a part of rewrite module and it most probably breaks expected behavior.
I used return
only for testing. Without it, you get a 405
, and no, it still doesn't work - cache won't purge.
@Znuff
May I ask, is your stack configured for per site PHP users? In which case, yup, this module will not work, its been long and well documented.
Also, the solution at the top using PHP will only work if Nginx and the PHP application share the same user.
However many stacks use this, and it does work. Most notably EasyEngine, but like I say, single user stacks.
However, this module: https://github.com/torden/ngx_cache_purge
Is a fork and works for multi-user stacks. How do I know? Because we have it compiled into our platform, and we have per application cache purging working fine with multitenancy LEMP stacks and each site in PHP user isolation.
First of all, if you are a Debian or Ubuntu (or derivatives) user, know that YES this is the github repository of the module packaged as
libnginx-mod-http-cache-purge
in your distribution. This module is also in use if you use Ondřej Surý's PPA.
For the LOVE OF GOD, Why was this information so difficult to find? I've been scouring the internet looking for an answer about both of these, and FINALLY I found it! Thank you so much @Znuff! You saved me a lot of wasted time and a lot more google searching with this information!
Sadly, as you dwelve deeper, you will find that
fastcgi_cache_purge
is only part of the subscription-model NGINX Plus, which I'm sure it's a great product, but I've learned the lesson that if you have to ask for what the price of a product is (they are not displaying it anywhere public), it's too expensive.Luckily, you can see that there are quite a few 3rd party modules for nginx that mention cache purging and fastcgi.
This is one of them. Or, I should say, this was one of them.
I've attempted all the possible configuration variants to get this to work, but alas, to no avail.
So to save you some time: DO NOT USE THIS MODULE, IT DOES NOT WORK
I followed THIS TUTORIAL from Linuxbabe.com and got this module working properly after building it from source for my version of Nginx mainline, specifically Nginx v1.21.4 on a Raspberry Pi 4.
EDIT: I actually thought this module WAS working, but after further inspection, it was not actually purging the cache as expected. This module might as well be dead.
I'm not saying wasting of time on it but it just not working as expected, so i build my own purge, kinda fast just in few minutes