Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expire assets cache in browsers when replacing fingerprinted files server via nginx

Tags:

nginx

assets

I'm serving a single page JavaScript application via nginx and when I deploy new version, I want to force browsers to invalidate their JS cache and request/use the newest version available.

So for example when I replace a file on the server's folder, named my-app-8e8faf9.js, with a file named my-app-eaea342.js, I don't want browsers to pull my-app-8e8faf9.js from their cache anymore. But when there is no new version available, then I still want them to read the assets from cache.

How do I achieve this with the nginx config? This is my existing config:

server {
  listen 80;

  server_name my.server.com;

  root /u/apps/my_client_production/current;
  index index.html;

  # ~2 seconds is often enough for most folks to parse HTML/CSS and
  # retrieve needed images/icons/frames, connections are cheap in
  # nginx so increasing this is generally safe...
  keepalive_timeout 10;
  client_max_body_size 100M;

  access_log /u/apps/my_client_production/shared/log/nginx.access.log;
  error_log /u/apps/my_client_production/shared/log/nginx.error.log info;

  location / {
    try_files $uri $uri/ =404;

    gzip_static on;
    expires max;
    add_header  Cache-Control public;

  }

  # Error pages
  error_page 500 502 503 504 /500.html;
}
like image 745
Matic Jurglič Avatar asked Jan 22 '16 11:01

Matic Jurglič


1 Answers

Invalidating cache by changing assets urls is a normal practice.

But for that to work you need your html files not to be cached forever so that browser will have some info when these names change.

So separate locations for html and assets. Matcher can be different, depending on how you store them, for example:

location / {
  try_files $uri $uri/ =404;
  gzip_static on;
  }

location ^~ /assets/ {
  gzip_static on;
  expires max;
  add_header Cache-Control public;
  }
like image 60
Vasfed Avatar answered Nov 15 '22 21:11

Vasfed