nginx: Using fastcgi_cache with try_files rewrites
PHP-FPM and try_rewrite
Often with PHP-based applications you rewrite non-existent (on the filesystem, anyway) URLs to a script that performs routing, often index.php
.
When using PHP-FPM, this often looks something like (incomplete example):
location / {
try_files $uri $uri/ /index.php;
}
location ~ [^/]\.php(/|$) {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
...
}
Response Caching
fastcgi_cache
is a great way to speed up cacheable pages, especially if you use a small tmpfs
volume for storage.
Most online references approximately show you how to configure the cache:
# In an http{} block
# Cache HTTP 200s from PHP-FPM for 1 hour, 60mb cache in /var/cache/nginx/fastcgi_cache.
fastcgi_cache_valid 200 1h;
fastcgi_cache_path /var/cache/nginx/fastcgi_cache levels=1:2 keys_zone=DEFAULT:10m max_size=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache DEFAULT;
but not how to include/exclude from caching depending on the URI.
So ...
Cache inclusion and exclusion
If we wanted to cache /routeX
(which would be served via index.php
via our try_files
directive), we would pass a map to fastcgi_cache_bypass
:
# Still in the http{} block
# 0 is cacheable, otherwise bypass fastcgi_cache entirely
map $request_uri $no_cache {
default 1;
~/routeX 0;
}
fastcgi_cache_bypass $no_cache;
The key here is to use $request_uri as the mapped variable rather than $uri. The latter is changed to index.php
by try_files
, which would mean the cache would always be bypassed!
For easier debugging, try add_header X-Cache $upstream_cache_status
in your FastCGI location
.