309

I use nginx to as the front server, I have modified the CSS files, but nginx is still serving the old ones.

I have tried to restart nginx, to no success and I have Googled, but not found a valid way to clear it.

Some articles say we can just delete the cache directory: var/cache/nginx, but there is no such directory on my server.

What should I do now?

Paulo Boaventura
  • 1,365
  • 1
  • 9
  • 29
Freewind
  • 193,756
  • 157
  • 432
  • 708
  • 1
    More details on your Nginx configuration would be of much help. Are you using `proxy_cache` ? – Alexander Azarov Jun 04 '11 at 12:13
  • No, I just used the default configuration, and I searched about string `cache`, not found it in the config files – Freewind Jun 04 '11 at 15:16
  • 5
    Nginx does not cache by default. – Alexander Azarov Jun 04 '11 at 17:12
  • 30
    Are you running in a virtualbox/vargant vm? If so, try turning off sendfile, as they don't play well together. – kolbyjack Jun 06 '11 at 14:22
  • @kolbyjack, no, it's running in a standalone server – Freewind Jul 04 '11 at 18:34
  • 9
    are you sure the caching is on the nginx side, then? Have you verified the behavior with a tool like curl? Often times, an issue like this is just client-side caching not requesting an updated resource because it's been told that the old resource will be valid for a long time by expires max; or something similar. – kolbyjack Jul 05 '11 at 14:31
  • @kolbyjack So should I leave sendfile on for live servers but off for virtualbox/vagrant vm? or I should keep it off at all times? – Kim Stacks Jun 25 '13 at 12:45
  • @kolbyjack: Thanks. Turning sendfile off solved a problem which had swallowed hours of time. Look like the way to go is to set sendfile off when in Vagrant, on for real servers. – mattandrews Jul 07 '13 at 02:40
  • I found that using google chrome in incognito was a way to eliminate browser cache without deleting all my history, so changes would update as I modified files and refreshed browser. – mauricio777 Sep 21 '16 at 16:15

25 Answers25

201

I had the exact same problem - I was running my nginx in Virtualbox. I did not have caching turned on. But looks like sendfile was set to on in nginx.conf and that was causing the problem. @kolbyjack mentioned it above in the comments.

When I turned off sendfile - it worked fine.

This is because:

Sendfile is used to ‘copy data between one file descriptor and another‘ and apparently has some real trouble when run in a virtual machine environment, or at least when run through Virtualbox. Turning this config off in nginx causes the static file to be served via a different method and your changes will be reflected immediately and without question

It is related to this bug: https://www.virtualbox.org/ticket/12597

Chris Stryczynski
  • 30,145
  • 48
  • 175
  • 286
Deepan Chakravarthy
  • 4,154
  • 7
  • 25
  • 21
149

You can also bypass/re-cache on a file by file basis using

proxy_cache_bypass $http_secret_header;

and as a bonus you can return this header to see if you got it from the cache (will return 'HIT') or from the content server (will return 'BYPASS').

add_header X-Cache-Status $upstream_cache_status;

to expire/refresh the cached file, use curl or any rest client to make a request to the cached page.

curl http://abcdomain.com/mypage.html -s -I -H "secret-header:true"

this will return a fresh copy of the item and it will also replace what's in cache.

Jason Wiener
  • 1,851
  • 1
  • 13
  • 13
  • 10
    Why can I only upvote this one time? I want to do a gazillion :) – Spock Oct 28 '15 at 07:42
  • 3
    This can only update cached pages when the new page is cacheable as well. If you have removed a page (404 or other errors are now served by the backend), the page now sends a Set-Cookie or a "Content-Control: private" header, the cached content will not be "invalidated". – rbu Feb 02 '16 at 10:17
  • 3
    This "add_header X-Cache-Status $upstream_cache_status;" is such a cool feature! – Maxim Masiutin Apr 24 '17 at 05:19
  • 1
    thanks a lot. nice tip for cache invalidation, there is so little tutorials about nginx – Ivan Semochkin Jun 05 '17 at 05:48
  • 5
    Has this changed since you posted? I can successfully get a fresh copy with the "secret-header" but as soon as I remove the header, I get the cached version again... – Pluc Aug 10 '17 at 19:30
  • 1
    Nothing works actually with proxy_cache. Looks like it depends on luck! – kidz Sep 07 '17 at 20:50
  • This worked for me. However, I am not sure where exactly the nginx cache is located ... – Mike5050 Nov 25 '17 at 14:49
  • Works exactly as advertised on my DigitalOcean Ubuntu 16.04 NodeJS instance. Struggled for hours with different methods. – Werner Weber Feb 11 '19 at 12:37
  • seems that method is not doing "re-cache" – neck Nov 15 '19 at 15:25
  • Do you enter the proxy_cache_bypass in the terminal? If so where? Or is this added to a file somewhere? – Jen Feb 09 '21 at 14:41
  • Definitely NOT working - still has HIT after execution and content is not updated. – france1 Jul 18 '22 at 08:19
  • AFAIK proxy_cache_bypass only bypasses cache... it doesn't recache. You'll have to manually delete de entire cache folder because the PURGE option is only available in the paid nginx version. – Alexei Martchenko Dec 12 '22 at 19:53
72

Unless you configured a cache zone via proxy_cache_path and then used it (for example in a location block), via: proxy_cache nothing will get cached.

If you did, however, then according to the author of nginx, simply removing all files from the cache directory is enough.

Simplest way: find /path/to/your/cache -type f -delete

Gnarfoz
  • 3,146
  • 1
  • 17
  • 15
  • i'm getting this in my error log after deleting the files: `[crit] 1640#0: unlink() "/path/to/cache/85/1cc5328db278b328f2c200c65179ad85" failed (2: No such file or directory)` – Collin Anderson Jun 30 '13 at 20:23
  • Repeatedly, or just once? It shouldn't be an actual problem. It probably just means that the cache manager tried to delete a file that you already deleted. Maybe reloading nginx (nginx -s reload) might help if you get the message repeatedly. (Not sure if that reinitializes the cache manager, too.) – Gnarfoz Jul 02 '13 at 17:50
  • 1
    yeah, I automatically clear the cache for my website by a script whenever I deploy a change, and reloading nginx doesn't fix it either. – Collin Anderson Jul 02 '13 at 21:13
  • Nop Nginx caches something even if you don't use proxy stuff, but it's a bug with Nginx + VirtualBox. – Thomas Decaux Aug 26 '13 at 09:52
  • 1
    That sounds rather vague. Could you elaborate on that? Doesn't seem like it's related to the topic at hand here. – Gnarfoz Sep 02 '13 at 09:14
  • 1
    Search nginx conf files for `proxy_cache_path` to find the path to your cache like `grep -r proxy_cache_path /etc/nginx/` Mine was set in `/etc/nginx/conf.d/proxy_cache.conf` as `/var/lib/nginx/proxy` – here Nov 12 '13 at 02:32
  • @ThomasDecaux: Yes, please tell us more about that bug - I think I'm a victim of it! I have a VM with nginx, the word "cache" does not appear in any of my config files, and turning off sendfile did not solve it for me. I know it's not browser cache because in PHP, `echo(file_get_contents("http://my.vm/css/style.css"));` will serve up the old content. – OsakaWebbie Apr 19 '14 at 21:48
  • Never mind - apparently there was a delayed reaction to the act of turning off sendfile and restarting nginx - the first time after that it was the same, but now it appears to be responding to changes. – OsakaWebbie Apr 19 '14 at 22:02
  • I had `proxy_cache_path /var/cache/nginx/cache` set in my `/etc/nginx/nginx.conf` I simply needed to delete the contents on this cache folder and then my website updated. `rm -rd /var/cache/nginx/cache *` – Philip Rego Sep 29 '19 at 00:28
  • It did not work. /var/cache/nginx is the path (find /var/cache/nginx -type f -delete) - and it's still cached. I don't get it. I just deleted the whole cahce directory content and that worked. – france1 Jul 18 '22 at 08:22
25

You can delete cache directory of nginx or You can search specific file:

grep -lr 'http://mydomain.pl/css/myedited.css' /var/nginx/cache/*

And delete only one file to nginx refresh them.

Freewind
  • 193,756
  • 157
  • 432
  • 708
Łukasz Sokolik
  • 251
  • 2
  • 3
  • 1
    To get the exact hit, you can append **$** to the search term. Like `grep -lr 'http://mydomain.pl/css/myedited.css$' /var/nginx/cache/*` – Jifeng Zhang Oct 17 '14 at 11:39
  • 1
    Unfortunately I got the following output `grep: /var/nginx/cache/*: No such file or directory` I'm using Ubuntu 14.04.3 LTS and nginx/1.8.1. Any idea? – b00r00x0 Feb 06 '16 at 14:46
  • Try the following to grep files under /var/nginx/cache: `sudo find /var/nginx/cache -type f -exec grep -l '/css/myedited.css' {} \;` – jaybrau Oct 09 '17 at 20:56
  • 1
    I believe it's /var/cache/nginx/* ( dir cache before nginx in path) – Randy Lam Mar 30 '20 at 12:10
20

I run a very simple bash script which takes all of 10 seconds to do the job and sends me a mail when done.

#!/bin/bash
sudo service nginx stop
sudo rm -rf /var/cache/nginx/*
sudo service nginx start | mail -s "Nginx Purged" me@gmail.com
exit 0
MitchellK
  • 2,322
  • 1
  • 16
  • 25
17

I had this problem also.

  • Could not find any nginx/cache folder
  • sendfile was off

My domain uses cloudflare.com for DNS (great service!). Aha! There it was:

cloudflare.com -> caching -> Purge Cache (I purged everything) That solved my problem!

Asle
  • 767
  • 2
  • 8
  • 22
15

There's two answers in this question.

  • One for nginx as reverse cache
  • Another for cleaning the browser cache by header input (this one)

Use:

expires modified +90d;

E.G.:

location ~* ^.+\.(css|js|jpg|gif|png|txt|ico|swf|xml)$ {
    access_log off;
    root /path/to/htdocs;
    expires modified +90d;
}
Thiago Macedo
  • 6,187
  • 1
  • 21
  • 22
deyes
  • 637
  • 6
  • 9
  • I tried this implementation because i'm having similar issue. However, after I made the change - it shows the default Nginx page. I'm using Niginx as LB with proxy, do I need to change root maybe? – Aaron Sep 20 '15 at 08:41
11

I found this useful

grep -lr 'jquery.js' /path/to/nginx/cache/folder/* | xargs rm

Search, and if found then delete.

agustik
  • 111
  • 1
  • 2
11

We have a very large nginx cache (gigabytes) that we occasionally need to wipe. I've worked out a script that instantly clears the cache (as far as Nginx is concerned) and then removes the cache directory without starving the main application for disk I/O.

In summary:

  1. Move the cache folder to a new location (on the same filesystem!) (this doesn't disrupt any open file descriptors)
  2. Recreate the original cache folder, empty
  3. Reload Nginx (graceful reload, where nginx lets old workers finish in-progress requests)
  4. Remove old cached data

Here's the script, tailored to Ubuntu 16.04 LTS, with the cache located at /mnt/nginx-cache:

#!/bin/bash
set -e

TMPCACHE=`mktemp --directory --tmpdir=/mnt nginx-cache-XXXXXXXXXX`
TMPTEMP=`mktemp --directory --tmpdir=/mnt nginx-temp-XXXXXXXXXX`

# Move the old cache folders out of the way
mv /mnt/nginx-cache $TMPCACHE
mkdir -p /mnt/nginx-cache
chmod -R 775 /mnt/nginx-cache
chown www-data:www-data /mnt/nginx-cache

mv /mnt/nginx-temp $TMPTEMP
mkdir -p /mnt/nginx-temp
chmod -R 775 /mnt/nginx-temp
chown www-data:www-data /mnt/nginx-temp

# Tell Nginx about the new folders.
service nginx reload

# Create an empty folder.
rm -rf /mnt/empty
mkdir -p /mnt/empty

# Remove the old cache and old temp folders w/o thrashing the disk...
# See http://serverfault.com/questions/546177/how-to-keep-subtree-removal-rm-rf-from-starving-other-processes-for-disk-i
# Note: the `ionice` and `nice` may not actually do much, but why not?
ionice -c 3 nice -19 rsync -a --delete /mnt/empty/ $TMPCACHE
ionice -c 3 nice -19 rsync -a --delete /mnt/empty/ $TMPTEMP
rm -rf $TMPCACHE
rm -rf $TMPTEMP

rm -rf /mnt/empty

And in case it's helpful, here's the Nginx config we use:

upstream myapp {
    server localhost:1337 fail_timeout=0;
}

proxy_cache_path /mnt/nginx-cache/app levels=2:2:2 keys_zone=app_cache:100m inactive=1y max_size=10g;
proxy_temp_path  /mnt/nginx-temp/app;

server {
    listen   4316 default;
    server_name  myapp.com;

    location / {
        proxy_pass http://appserv;
        proxy_cache app_cache;
        proxy_cache_valid 200 1y;
        proxy_cache_valid 404 1m;
    }
}
David Eyk
  • 12,171
  • 11
  • 63
  • 103
10

In my nginx install I found I had to go to:

sudo rm -rf /opt/nginx/cache

in that directory. If you know the path to your nginx install and can find the cache directory the same may work for you. Be very careful with the rm -rf command, if you are in the wrong directory you could delete your entire hard drive.

SagarPPanchal
  • 9,839
  • 6
  • 34
  • 62
Ganesh Shankar
  • 4,826
  • 8
  • 43
  • 56
5

For those who other solutions are not working, check if you're using a DNS service like CloudFlare. In that case activate the "Development Mode" or use the "Purge Cache" tool.

Leopoldo Sanczyk
  • 1,529
  • 1
  • 26
  • 28
5

Please take note that proxy_cache_bypass can give you a world of hurt if your app doesn't return a cacheable response for that specific request where you trigger it.

If for example your app sends a cookie with every first request, then a script which triggers proxy_pass_bypass via curl will probably get that cookie in the answer, and nginx will not use that response to refresh the cached item.

dwt
  • 128
  • 1
  • 7
4

On my server, the nginx cache folder is at /data/nginx/cache/

So I removed it only: sudo rm -rf /data/nginx/cache/

Hope this will help anyone.

Brilliant-DucN
  • 706
  • 8
  • 12
4

For those who have tried deleting the nginx cache files, and either it hasn't worked or has worked intermittently, have a look at your setting for open_file_cache. If this is enabled and configured to cache a file descriptor for a long time, then Nginx may still see a version of the cached file, even after you've deleted it from disk. I had to reduce open_file_cache_valid to 1s (I'm not certain if this is essentially the same as disabling the file cache completely).

SilentMiles
  • 624
  • 6
  • 8
3
find /etc/nginx/cache_folder -type d -exec rm -rvf {} \;
mkdir /etc/nginx/cache_folder
service nginx restart

Be careful to properly specify the correct path.

colapsnux
  • 872
  • 2
  • 15
  • 32
2

There is one right method to remove only cache-files, which matches any KEY. For example:

grep -lr 'KEY: yahoo' /var/lib/nginx/cache | xargs rm -rf

This removes all cache-files, which matches to KEY "yahoo/*", if in nginx.conf was set:

proxy_cache_key $host$uri;
2

If you want to clear the cache of specific files then you can use the proxy_cache_bypass directive. This is how you do it

location / {
    proxy_cache_bypass $cookie_nocache $arg_nocache;
    # ...
}

Now if you want bypass the cache you access the file by passing the nocache parameter

http://www.example.com/app.css?nocache=true

Sajjad Ashraf
  • 3,754
  • 1
  • 34
  • 35
1

You can add configuration in nginx.conf like the following.

...
http {
proxy_cache_path  /tmp/nginx_cache levels=1:2 keys_zone=my-test-cache:8m max_size=5000m inactive=300m;

server {
    proxy_set_header X- Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_cache my-test-cache;
    proxy_cache_valid  200 302  1m;
    proxy_cache_valid  404      60m;
    proxy_cache_use_stale   error timeout invalid_header updating;
    proxy_redirect off;

    ....
}
...
}

From above, a folder named "nginx_cache" is dynamicly created in /tmp/ to store cached content.

1

We use nginx for caching lots of stuff. There are tens of thousands of items in the cache directory. To find items and delete them, we have developed some scripts to simplify this process. You can find link to the code repository containing these scripts below:

https://github.com/zafergurel/nginx-cache-cleaner

The idea is simple. To create an index of the cache (with cache keys and corresponding cache files) and search within this index file. It really helped us to speed-up finding items (from minutes to sub-second) and delete them accordingly.

Zafer
  • 2,180
  • 16
  • 28
1

In my case, touch that Css file, make it looks like resources changed (actually touch does nothing to the file, except change last modify time), so browser and nginx will apply latest resources

zmou-d
  • 834
  • 1
  • 8
  • 14
1

Well, in common cache problem situations (browser cached, proxy cached, web-server cached) you can use common known decision of cache problem of rare changing content like CSS or JS files - by adding an URI param to their links:

not <link rel="stylesheet" type="text/css" href="https://example.com/stacks.css">

but <link rel="stylesheet" type="text/css" href="https://example.com/stacks.css?v=3b16a418cc4c">

Like StackOverflow does too. :)

FlameStorm
  • 944
  • 15
  • 20
0

I was experiencing a kind of similar issue:

System setup and Problem: (On a virtualbox I'm web hosting using ubuntu and nginx - PHP webpage refreshes did not reflect changes to external css file). I'm developing website on windows machine and transferring files to nginx via shared folder. It seems nginx does not pick up changes to css file (refreshing in any fashion does not help. Changing css file name is only thing that worked)

Solution: On VM find shared file (css file in my case). Open with nano and compare to file in windows share (they appear identical). On VM save shared file with nano. All changes are now reflected in browser. Not sure why this works but it did in my case.

UPDATE: After rebooting the VM server the problem returned. Following the instructions under Solution made the css responsive to updates again

Mr G
  • 1
  • 3
0

There are already a lot of answers out there but I think I have a useful addition;

I'm running a Homestead box with Hyper-V and I had a laravel project up and running on nginx.

I didn't have a cache in my nginx folder in /etc/

When i visited my website, I was getting server old views and css files.

What solved it for me after searching a wasting a lot of time looking at my nginx config and trying things out was using PHP artisan.

Run the following command in the folder where artisan is installed [root dir of laravel project]: php artisan optimize:clear

this command clears all the caches, and when i refreshed my webpage, Finaly it updated with all the changes.

Hope this helps stranded souls like me :)

EDIT: I would have posted this as a comment to one of the already existing answers if I had 50 reputation.. [I have only 43 so far]

Xilef
  • 81
  • 11
  • Is this actually related to nginx cache that the question is about? – de1 Jan 28 '21 at 14:55
  • It is not related to nginx, but I thought my problem was and I ended up here. As there are already a lot of answers about nginx, I'm hoping to help those that don't realize it's a homestead/laravel issue (like me) and end up stranded here. Basicly if some1 else would have answered what I wrote, it would have saved me a lot of time. So that's why I took the time to reply.. But if my input isn't appreciated, I will delete my post.. – Xilef Jan 29 '21 at 09:28
0

This answer is mainly a summary:

Expires, Age, Cache-Control are HTTP concepts
Check these links:

nginx settings for same, check below link:

To not cache, below might help: (could set less time for cache to revalidate sooner):

expires    0;
add_header Cache-Control private;

To clear cache:
. Delete files under cache directory (/var/nginx/cache/)
. Reload (not restart) the nginx - nginx -s reload
See https://forum.nginx.org/read.php?2,2600,2602

Manohar Reddy Poreddy
  • 25,399
  • 9
  • 157
  • 140
-2

In my case it was the enabled opcache in /etc/php/7.2/fpm/php.ini (Ubuntu):

opcache.enable=1

Setting it to 0 made the server loading the latest version of the (php)files.

FullStack Alex
  • 1,783
  • 19
  • 31