NGINX : Cache when X-Accel-Expires is set
I have added a X-Accel-Expires header on my static contents as well as a Last-Modified header. I would like to know whats the correct setting to cache those elements without caching anything else.
This is what I have at the moment but it doesn't cache anything :
http {
include /etc/nginx/mime.types;
access_log /var/log/nginx/access.log;
sendfile on;
client_max_body_size 2000m;
keepalive_timeout 65;
tcp_nodelay on;
gzip on;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
ssl_certificate /etc/nginx/chain.pem;
ssl_certificate_key /etc/nginx/key.key;
proxy_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=cache:30m max_size=1G;
proxy_temp_path /var/lib/nginx/proxy 1 2;
proxy_cache_use_stale error timeout invalid_header http_502;
server {
listen 80;
server_name domain;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 700;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Solution 1:
To cache stuff, first you need to create a proxy cache path within the http
context, like this:
proxy_cache_path /var/cache/nginx/site1 levels=1:2 keys_zone=site1:10m max_size=1G;
Then you can also optionally define the proxy cache key. Any request that has the same cache key as a cached entry, will receive the cached reply, if there is one. But default may already be good enough, so, that's entirely optional.
Then to enable the cache in a given context, just mention which cache should be used, like this:
proxy_cache site1;
According to the description of the proxy cache valid directive, nginx already respects X-Accel-Expires
and acts on it, so, you're basically done at this point. Since you don't want to cache anything that doesn't include X-Accel-Expires
, then you probably want to add a value of 0 as the default valid time (setting X-Accel-Expires
within your content should overwrite this default value).
proxy_cache_valid 0m;
I shall presume that other than for the lack of any caching, your config file is otherwise valid, and your proxying itself already works.
Then, basically, all you need to do to fix your config is add the following to your http
, server
or location
context:
proxy_cache cache;
proxy_cache_valid 0m;
(Also, you might want to ensure that the cache path exists and has correct permissions, of course.)
Regarding the mentioned habrahabr article/example, I don't think it's actually correct to be including $http_if_modified_since
in the cache key, because you can potentially end up with a lot of multi-cached entries, effectively wasting your cache.
Also note that nginx likely doesn't proxy X-Accel-Expires
header -- it only uses it internally, and IIRC may not serve this header forward. To alter such behaviour, you have to explicitly ask for it to be proxied, too (in case you want to debug your content through nginx, and see how your app sets the header etc):
proxy_pass_header "X-Accel-Expires";
Solution 2:
There is a good howto about using of X-Accel-Expires
header in nginx on Russian IT blog.
I think, it may be very useful in your case.