Table of Contents
We already made a number of tutorials about Nginx, one of best web servers available for Linux - which can also be used as a reverse proxy, load balancer and HTTP cache: in case you missed them, you can get a comprehensive list by clicking here.
In this post we'll talk about the awesome ngx_cache_purge module by FRiCKLE, which is an excellent way to manage the Nginx cache folder(s) when we use it as a Reverse Proxy with caching features. The module works with all supported proxy types - including FastCGI, Proxy-Cache, SCGI and uWSGI. Unfortunately, the module is not shipped with the vanilla Nginx build which we could install on your CentOS machine by typing the sudo yum install nginx command: in order to use that, we need to install a custom Nginx build package (called error/nginx) from an external repo, which is also not included in the default yum repository database.
Add the error/nginx repository
The first thing we need to do is to create a new .repo file that will host the custom repository from where we'll fetch & install the modded version of Nginx. Navigate to the /etc/yum.repos.d/ folder and then create a new file - for example, error-nginx.repo - and fill it with the following content:
1 2 3 4 5 6 7 8 9 10 |
[error-nginx] name=Copr repo for nginx owned by error baseurl=https://copr-be.cloud.fedoraproject.org/results/error/nginx/epel-7-$bas$ type=rpm-md skip_if_unavailable=True gpgcheck=1 gpgkey=https://copr-be.cloud.fedoraproject.org/results/error/nginx/pubkey.gpg repo_gpgcheck=0 enabled=1 enabled_metadata=1 |
Once done, you can proceed with your sudo yum install nginx command or even update your current installation by typing sudo yum update nginx .
How to delete the cache
Nginx built with the ngx_cache_purge module supports various alternative method for selectively and/or globally deleting the cache. Some of them require to be configured within the /etc/nginx/nginx.conf file, while others can be used by directly accessing the machine via SSH:
- Delete the entire cache folder
- Refresh items with the BYPASS Method
- Erase items with the PURGE Method
- Erase items with the /purge URL Method
Let's see each one of them in details.
Delete the entire cache folder
Nginx proxy cache is stored in a folder structure defined in our nginx.conf file - the /var/cache/nginx folder, if you used our nginx.conf configuration sample - which we can selectively delete specific items from or delete everything to empty the entire cache.
Here's the terminal command to empty the entire cache:
1 |
rm -R /var/cache/nginx/* |
Delete specific items is a bit more complicated, because we should create an md5 hash of the full URL we want to purge and then delete the specific folder and subfolder recursively in the proxy_cache_path folder. It's worth noting that most WordPress plugins that deal with Nginx cache can do that automatically, hence - if you use WordPress - we strongly suggest to use one of them.
The BYPASS Method
The BYPASS Method is definitely the best way to invalidate and refresh the Nginx reverse proxy cache. with proxy_cache_bypass we can force Nginx to fetch a new version of the URL from the web server and replace the old outdated version with the new fresh version. If you used our nginx.conf configuration sample, the proxy_cache_bypass feature is already implemented; if you need to implement it from scratch, you have to add the following settings to the server block within your nginx.conf file:
1 2 3 4 5 6 |
set $bypass 0; # security for bypass so localhost can empty cache if ($remote_addr ~ "^(127.0.0.1)$") { set $bypass $http_secret_header; } |
... and then the following within the main location block:
1 2 |
# CACHE CONFIGURATION result proxy_cache_bypass $bypass; |
As we can see, we enabled the secret header for incoming requests from the web server and reverse proxy so we can test using the secret header with cURL from those servers.
Here's the terminal command to force a BYPASS:
1 |
curl -I https://wp-bullet.com -H "secret-header: true" |
If we do that from the same server that runs Nginx, we should see the following response output, showing BYPASS in the X-Cache header:
1 2 3 4 5 6 7 |
HTTP/1.1 200 OK Server: nginx/1.8.1 Date: Sun, 25 Mar 2018 17:30:00 GMT Content-Type: text/html; charset=UTF-8 Connection: keep-alive Vary: Accept-Encoding X-Cache: BYPASS |
If you try to do that from any other server, we should just see a X-Cache: HIT response. Needless to say, we can add other IP addresses to the above IF condition within the server block to authorize the BYPASS method from additional trusted IP addresses.
The PURGE Method
To enable the PURGE method we have to add the following configuration settings within the location block of our nginx.conf file:
1 2 |
# configure proxy-cache-purge proxy_cache_purge PURGE from 127.0.0.1; |
You can white-list one or more IP addresses/masks by separating them with a single space.
Once done, we can issue a PURGE request using this terminal command:
1 |
curl -X PURGE -I https://www.our-website.com |
If the request comes from an authorized IP (127.0.0.1 in the above example), the proxy_cache_purge module will automatically translate the request into the md5 hash of the URL and delete the item from the proxy_cache_path folder specified in the nginx reverse proxy virtual host. If the file is found, we will get a 200 response meaning that the PURGE was successfully done:
1 2 3 4 5 6 |
HTTP/1.1 200 OK Server: nginx/1.8.1 Date: Sun, 25 Mar 2018 17:30:00 GMT Content-Type: text/html Content-Length: 277 Connection: keep-alive |
If Nginx does not have that specific URL cached, we will get a standard HTTP 404 - Not Found error; also, if the request comes from a non-whitelisted IP address, the caller will receive a HTTP 403 - Forbidden error.
The /purge URL Method
This method uses a specific URL to call the same proxy_cache_purge method we introduced above: again, to make it work, we need to add the following settings within our nginx.conf configuration file's server block:
1 2 3 4 5 6 7 |
# allows purging via special URL location ~ /purge(/.*) { allow 127.0.0.1; # allow some_other_ip_or_mask; deny all; proxy_cache_purge edge-cache $scheme$host$1; } |
Be sure to replace edge-cache with the keys_zone specified in the proxy_cache_path configuration setting.
Once done, we can purge via URL with the following cURL comand:
1 |
curl https://wp-bullet.com/purge/ -I |
If the IP address is present in the allow list and the home page was cached by Nginx reverse proxy we will see the following result:
1 2 3 4 5 6 |
HTTP/1.1 200 OK Server: nginx/1.8.1 Date: Wed, 25 Mar 2018 17:30:00 GMT Content-Type: text/html Content-Length: 277 Connection: keep-alive |
Again, if Nginx does not have that specific URL cached we will get a standard HTTP 404 - Not Found error; if the request comes from a non-whitelisted IP address, the caller will receive a HTTP 403 - Forbidden error.
Conclusions
That's it for now: if you have other suggestions, feel free to add them to the comments section below!