nginx as cache proxy not caching anything
Solution 1
Make sure your backend does not return Set-Cookie
header. If Nginx sees it, it disables caching.
If this is your case, the best option is to fix your backend. When fixing the backend is not an option, it's possible to instruct Nginx to ignore Set-Cookie
header
proxy_ignore_headers "Set-Cookie";
proxy_hide_header "Set-Cookie";
See the documentation
proxy_ignore_header
will ensure that the caching takes place. proxy_hide_header
will ensure the Cookie payload is not included in the cached payload. This is important to avoid leaking cookies via the NGINX cache.
Solution 2
I would like to add that multiple configuration options and combinations can disable proxy caching in Nginx. Unfortunately this is poorly documented.
In my configuration I set proxy_buffering on
and it enabled caching as expected.
Solution 3
after going through multiple answers and comments, i found this configuration finally works:
10m
= 10mb
key cache, max_size
to 2GB
, inactive=120m
(refresh from source after 120minutes of inactive), use_temp_path=off
(to reduce io)
proxy_cache_valid
- cache status of 200
and 302
for 60 minutes
proxy_cache_path /tmp/cache levels=1:2 keys_zone=default_cache:10m max_size=2g
inactive=120m use_temp_path=off;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_valid 200 302 60m;
server {
listen 80;
server_name example.com;
# https://www.nginx.com/blog/nginx-caching-guide
location / {
proxy_cache default_cache;
proxy_buffering on;
proxy_ignore_headers Expires;
proxy_ignore_headers X-Accel-Expires;
proxy_ignore_headers Cache-Control;
proxy_ignore_headers Set-Cookie;
proxy_hide_header X-Accel-Expires;
proxy_hide_header Expires;
proxy_hide_header Cache-Control;
proxy_hide_header Pragma;
add_header X-Proxy-Cache $upstream_cache_status;
proxy_pass http://ip-of-host:80;
#set $memcached_key "$uri?$args";
#memcached_pass 127.0.0.1:11211;
# error_page 404 502 504 = @fallback;
}
}
Related videos on Youtube
Bruno Faria
I'm the Principal Consultant of Ignia in the Cloud & Infrastructure team based in Melbourne with a heavy focus on cloud infrastructure, architecture and the Microsoft cloud stack. I'm also a Microsoft Most Valuable Professional (MVP) in Azure, an award given to exceptional, independent community leaders who share their passion, technical expertise, and real-world knowledge of Microsoft products with others. I have more than 14 years designing and implementing solutions to provide scalable and resilient services, automated (cost-effective) operational infrastructure, performance and data protection for highly available systems.
Updated on May 05, 2022Comments
-
Bruno Faria about 2 years
I'm trying to cache static content which are basically inside the paths below in virtual server configuration. For some reason files are not being cached. I see several folders and files inside the cache dir but its always something like 20mb no higher no lower. If it were caching images for example would take at least 500mb of space.
Here is the nginx.conf cache part:
** nginx.conf ** proxy_cache_path /usr/share/nginx/www/cache levels=1:2 keys_zone=static$ proxy_temp_path /usr/share/nginx/www/tmp; proxy_read_timeout 300s;
Heres the default virtual server.
**sites-available/default** server { listen 80; root /usr/share/nginx/www; server_name myserver; access_log /var/log/nginx/myserver.log main; error_log /var/log/nginx/error.log; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; location ~* ^/(thumbs|images|css|js|pubimg)/(.*)$ { proxy_pass http://backend; proxy_cache static; proxy_cache_min_uses 1; proxy_cache_valid 200 301 302 120m; proxy_cache_valid 404 1m; expires max; } location / { proxy_pass http://backend; } }
-
André Perazzi over 12 yearsHave tou tryed to turn on error logging?
-
Bruno Faria over 12 yearsyes. nothing conclusive.
-
-
Bruno Faria over 12 yearsactually it was not set-cookie but cache-control. I found out that IIS was actually caching static files and the response to nginx was to not cache those files prolly because it was already caching it. Once i removed those files from iis cache it worked. :)
-
dlrust about 10 yearsThis worked for me on nginx in front of a django backend. Otherwise it wasn't caching at all
-
Amr Mostafa about 10 yearsIf I understand correctly then you almost always want to also set
proxy_hide_header "Set-Cookie"
or you will be serving all your visitors the cookies that were generated for the first user who requested the resource. -
Sam Saffron almost 9 years@alexander I updated your answer, proxy_ignore_headers without proxy_hide_header is a huge security risk.
-
Kaworu over 8 yearsin case someone else has the same problem i had:
proxy_buffering off;
will prevent caching -
Meglio about 8 yearsSo, how is
proxy_buffering on
related, may you explain please? -
Overbryd about 8 yearsI was looking for some official documentation on the relation between proxy buffering and proxy caching, but I could not find any good resources to cite here. I added this answer, because switching
proxy_buffering
off simply disables any configured caching behaviour, without a warning or anything else. My guess is that without buffering the nginx has no way to store and thus cache a response from the server it is proxying to. This answer hints some things, maybe even ask Tero Kilkanen who gave the answer: serverfault.com/a/692585/144118 -
dr.dimitru about 8 yearsMade my day. I've spent 3 days! To figure out what the **** wrong with our config. Big, great thank you @Overbryd , from bottom of my heart.
-
Jason about 8 yearsThat could possibly be systemd, or a patch from RedHat. Try systemctl cat nginx.service and see if there is an option in there to give chroot it or something similar
-
luqo33 almost 8 yearsThis reply advises to hide the
Set-Cookie
header from the client. How is that suppose to work out for sites that rely heavily on cookies - e.g. e-commerce. What's going to happen to user's cart, checkout, etc. I'd like to hear more about why would that by an advised think to do. -
Bubonic Pestilence over 7 years@Overbryd gj! was fighting nginx for 2 days, and your answers is freaking awesome!
-
Dave over 7 yearswth - this is not mentioned in ANY caching example on the web that I've found after 3 hours of searching!
-
antonbormotov almost 7 yearsMost probably you have to specify
proxy_cache_path /tmp/my_nginx_cache use_temp_path=off ...
, otherwise nginx appends as prefixproxy_temp_path
, which is set to/tmp/systemd-private-phJlfG/
in your case. -
Joshua Miller over 6 yearsConfirmed - 'PrivateTmp=true' in the nginx.service systemd unit file from RHEL nginx rpm. If you put your cache under /tmp, it won't be persistent in this setup (restart of nginx will result in it getting a fresh new cache dir).
-
siride over 6 years@luqo33: this only removes cookies from cached content via a proxy. Presumably if you are proxying to a server that is doing e-commerce stuff, you wouldn't cache or block cookies.
-
Mark almost 6 yearsThere seems to be a known issue with Centos 7 and Nginx caching
-
Khom Nazid over 5 years@JoshuaMiller so how did you solve this issue? I have the same issue.
-
davidtgq over 4 yearsThank you! Nginx mysteriously started to not cache map tiles from OSM anymore, I thought it was a config problem... turns out they just started sending out cookies with each tile >:(
-
pva over 3 yearsOpened ticket to document this crap: trac.nginx.org/nginx/ticket/2048
-
Hoang about 3 yearsGood and clear answer. I followed and fixed my issues.