Freewind
Freewind

Reputation: 198188

How to clear the cache of nginx?

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?

Upvotes: 325

Views: 539607

Answers (26)

Alex from Jitbit
Alex from Jitbit

Reputation: 60556

To anyone wondering why this answer has stopped working:

curl sends a request with a different Accept-Encoding header than your browser. Nginx will cache different versions based on Accept-Encoding header i.e. gzipped/ungzipped and their implementation is sometimes buggy.

To clear the proxy cache for all compression options you might want to send your curl like this (to emulate the browser headers):

curl -v -H "secret-header: true" -H "Accept-Encoding: gzip, deflate, br" https://yoururl.goes.here

P.S. A better option would be to disable gzip compression at the upstream server altogether. This way it will always serve uncompressed response to the proxy and the compression will be handle at the proxy level. And you can clear you cache without worrying about the headers.

gzip off; # put this at the upstream server!

Upvotes: 1

Manohar Reddy Poreddy
Manohar Reddy Poreddy

Reputation: 27395

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

Upvotes: 0

Ganesh Shankar
Ganesh Shankar

Reputation: 4864

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.

Upvotes: 13

Xilef
Xilef

Reputation: 81

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]

Upvotes: 0

Zafer
Zafer

Reputation: 2190

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.

Upvotes: 1

FlameStorm
FlameStorm

Reputation: 1004

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. :)

Upvotes: 1

zmou-d
zmou-d

Reputation: 914

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

Upvotes: 0

FullStack Alex
FullStack Alex

Reputation: 2083

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.

Upvotes: -2

Deepan Chakravarthy
Deepan Chakravarthy

Reputation: 4324

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

Upvotes: 207

Sajjad Ashraf
Sajjad Ashraf

Reputation: 3844

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

Upvotes: 2

David Eyk
David Eyk

Reputation: 12521

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;
    }
}

Upvotes: 11

MitchellK
MitchellK

Reputation: 2612

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" [email protected]
exit 0

Upvotes: 22

Asle
Asle

Reputation: 827

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!

Upvotes: 23

SilentMiles
SilentMiles

Reputation: 692

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).

Upvotes: 4

Mr G
Mr G

Reputation: 1

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

Upvotes: 0

dwt
dwt

Reputation: 138

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.

Upvotes: 5

colapsnux
colapsnux

Reputation: 942

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.

Upvotes: 3

Leopoldo Sanczyk
Leopoldo Sanczyk

Reputation: 1609

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.

Upvotes: 5

Brilliant-DucN
Brilliant-DucN

Reputation: 724

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.

Upvotes: 4

Ivan BlaBlaBla
Ivan BlaBlaBla

Reputation: 21

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;

Upvotes: 2

deyes
deyes

Reputation: 657

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;
}

Upvotes: 16

Jason Wiener
Jason Wiener

Reputation: 1899

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.

Upvotes: 153

austinzmchen
austinzmchen

Reputation: 27

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.

Upvotes: 1

agustik
agustik

Reputation: 111

I found this useful

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

Search, and if found then delete.

Upvotes: 11

Łukasz Sokolik
Łukasz Sokolik

Reputation: 271

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.

Upvotes: 27

Gnarfoz
Gnarfoz

Reputation: 3236

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

Upvotes: 72

Related Questions