nginx as cache proxy not caching anything

44,267

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;
    }
}
Share:
44,267

Related videos on Youtube

Bruno Faria
Author by

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, 2022

Comments

  • Bruno Faria
    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
      André Perazzi over 12 years
      Have tou tryed to turn on error logging?
    • Bruno Faria
      Bruno Faria over 12 years
      yes. nothing conclusive.
  • Bruno Faria
    Bruno Faria over 12 years
    actually 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
    dlrust about 10 years
    This worked for me on nginx in front of a django backend. Otherwise it wasn't caching at all
  • Amr Mostafa
    Amr Mostafa about 10 years
    If 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
    Sam Saffron almost 9 years
    @alexander I updated your answer, proxy_ignore_headers without proxy_hide_header is a huge security risk.
  • Kaworu
    Kaworu over 8 years
    in case someone else has the same problem i had: proxy_buffering off; will prevent caching
  • Meglio
    Meglio about 8 years
    So, how is proxy_buffering on related, may you explain please?
  • Overbryd
    Overbryd about 8 years
    I 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
    dr.dimitru about 8 years
    Made 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
    Jason about 8 years
    That 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
    luqo33 almost 8 years
    This 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
    Bubonic Pestilence over 7 years
    @Overbryd gj! was fighting nginx for 2 days, and your answers is freaking awesome!
  • Dave
    Dave over 7 years
    wth - this is not mentioned in ANY caching example on the web that I've found after 3 hours of searching!
  • antonbormotov
    antonbormotov almost 7 years
    Most probably you have to specify proxy_cache_path /tmp/my_nginx_cache use_temp_path=off ..., otherwise nginx appends as prefix proxy_temp_path, which is set to /tmp/systemd-private-phJlfG/ in your case.
  • Joshua Miller
    Joshua Miller over 6 years
    Confirmed - '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
    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
    Mark almost 6 years
    There seems to be a known issue with Centos 7 and Nginx caching
  • Khom Nazid
    Khom Nazid over 5 years
    @JoshuaMiller so how did you solve this issue? I have the same issue.
  • davidtgq
    davidtgq over 4 years
    Thank 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
    pva over 3 years
    Opened ticket to document this crap: trac.nginx.org/nginx/ticket/2048
  • Hoang
    Hoang about 3 years
    Good and clear answer. I followed and fixed my issues.