NGINX proxy default cache time with Cache-Control and no expiration

13,849

Solution 1

You'd probably be better off setting or rewriting cache control headers inside Nginx. I have a tutorial on this here, and part one of the tutorial has downloadable config files. The key parts are below

You need headers_more for these to work. Some distributions include this, some don't and you need to build from source - which is pretty easy and is included in my tutorial.

Copied from Tutorial

We use a couple of different techniques to set cache control headers. First off we clear out any existing headers, like the very old Pragma which is not useful any more, clearing Expires headers (which is probably pointless since we set them later), and we clear the Server name for security.

more_clear_headers "Pragma"; more_clear_headers Server; more_clear_headers "Expires";

Then we can set the header manually. For image we use quite a long expires time

add_header Cache-Control "public, max-age=691200, s-maxage=691200";

For pages we keep it shorter – many sites will need this much shorter

add_header Cache-Control "public, max-age=86400, s-maxage=86400";

In some places we use an alternative format, for convenience.

expires 8d;

Example Nginx Configuration

An example Nginx server (with some parts missing like SSL setup)

# Caching. Putting the cache into /dev/shm keeps it in RAM, limited to 10MB, for one day.
# You can move to disk if you like, or extend the caching time

fastcgi_cache_path /dev/shm/nginxcache levels=1:2 keys_zone=CACHE:50m inactive=1440m; #RAM

# This needs to match your PHP configuration. Port is sometimes 9000 ****
upstream php {
  server 127.0.0.1:9001;
}

server {
  server_name www.example.com;
  listen 443 ssl http2;

  root /var/www/***folder;

    location ~*  \.(jpg|jpeg|png|gif|css|js|ico|svg)$ { 
  log_not_found off; access_log off;

    # Set up caching - 8 days for static resources
    # Remove the old unnecessary Pragma and hide the server version
    more_clear_headers "Cache-Control";
    add_header Cache-Control "public, max-age=691200, s-maxage=691200";
    more_clear_headers Server; more_clear_headers "Pragma"; mo  re_clear_headers "Expires";
}


  # PHP requests
  location ~ \.php$ {
    fastcgi_keep_conn on;
    fastcgi_intercept_errors on;
    fastcgi_pass   php;
    include        fastcgi_params;
    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;

    # Use the cache defined above. Cache 200 (success) status's, for 24 hours, and cache
    # specific other status's for an hour. This helps mitigate DDOS attacks.
    # Only cache GET and HEAD requests
    fastcgi_cache CACHE;
    fastcgi_cache_valid 200 1440m;
    fastcgi_cache_valid 403 404 405 410 414 301 302 307 60m;
    add_header X-Cache $upstream_cache_status;

    fastcgi_cache_methods GET HEAD; 
    fastcgi_cache_bypass $skip_cache;
    fastcgi_no_cache $skip_cache;

    # Set the cache control headers we prepared earlier. Remove the old unnecessary Pragma and hide
    # the server version. Clearing existing headers seems necessary
    more_clear_headers "Cache-Control";
    add_header Cache-Control $cacheControl;
    more_clear_headers "Pragma"; more_clear_headers Server; more_clear_headers "Expires";
  }
}

Solution 2

That is right, by default, with just proxy_cache configured, nginx only caches responses that have max-age set in the Cache-Control header.

Without any Cache-Control header or just Cache-Control: public nginx doesn't cache the response (i.e. you get each time X-Cache-Status: MISS when you also configure add_header X-Cache-Status $upstream_cache_status;).

You can configure a default caching time for responses without a Cache-Control header or ones without a max-age field in a Cache-Control header:

    # for 200, 301, 302 responses
    proxy_cache_valid     10m;
    # for all other responses
    proxy_cache_valid any 1m;

That means a Cache-Control header has precedence over a proxy_cache_valid setting and there are no defaults for proxy_cache_valid.

Share:
13,849

Related videos on Youtube

dlrust
Author by

dlrust

Updated on September 18, 2022

Comments

  • dlrust
    dlrust over 1 year

    I have caching enabled on an NGINX proxy.

    As I understand it, as long as I'm not ignoring the Cache-Control header in my proxy configuration (proxy_ignore_headers), the cache time before expiration can be set from the origin server using Cache-Control = max-age=XXXX.

    But what would be the default cache time it would keep and use for something like Cache-Control: public? Is there a way to set a default maximum cache time for these resources?