Setting expires headers for static content served from nginx

Solution 1:

I prefer to do a more complete cache header, in addition to some more file extensions. The '?' prefix is a 'non-capturing' mark, nginx won't create a $1. It helps to reduce unnecessary load.

location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
    expires 30d;
    add_header Pragma public;
    add_header Cache-Control "public";
}

Solution 2:

server {
    ...

    location ~* \.css$ {
       expires 30d;
    }
    ...
}

The location directive

The expires directive


Solution 3:

I don't have enough reputation to comment on why the accepted answer would cause the files to no longer show up, but I figured it out and would like to help out!

Short version:

Make sure you have a root directory specified for your location block on images if you do not have a global one set!

Long version below:


First of all, my method of implementing this solution was really similar to this answer, where you write the rule (as in the accepted answer):

location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
    expires 30d;
    add_header Pragma public;
    add_header Cache-Control "public";
}

into a file img-cache.conf

and then include that file into your server {...} directive.

My example of somesite.com in my sites-available folder:

 #Image Caching
 include /etc/nginx/conf/img-cache.conf;

That way you can add the image caching location block to multiple sites you might be running.


Second of all, I have a situation where my /var/www/ contains two folders that I allow as public_html - secure and training, so I have to make specific location blocks in my site's server directive singling out these folders.

As such, I do not have a global root directory set.

So when you make your image location blocks, you may not be providing them with a root directory from which to look for the images in!

My solution was then to:

location ~ ^/training.+\.(?:ico|css|js|gif|jpe?g|png)$ {
        root /var/www/;
        expires 7d;
        add_header Pragma public;
        add_header Cache-Control "public";
        try_files $uri 404;
}

location ~ ^/.+\.(?:ico|css|js|gif|jpe?g|png)$ {
        root /var/www/secure;
        expires 7d;
        add_header Pragma public;
        add_header Cache-Control "public";
        try_files $uri 404;
}

Solution 4:

You can also set the expires to maximum. Here is the directive I use for css and js.

# Set css and js to expire in a very long time
location ~* ^.+\.(css|js)$ {
    access_log off;
    expires max;
}

Solution 5:

All the aforementioned solutions will deny the possibility to have different aliases for different paths. Also for the sake of having all your different cache expirations in one place you should use nginx map in the following way.

...

# Expires mappings
map $sent_http_content_type $expires {
    default                    off;
    text/html                  epoch;
    text/css                   max;
    application/javascript     7d;
    ~image/                    max;
}

...

server {
   listen ...;

   expires $expires;
   location /assets/ {
      # It is now possible to serve some resources from different path
      alias /var/www/my_other_path/
   }

   # and have them all have same expirations
   location / {
       try_files $uri $uri/ /index.html;
   }
...
}

Off disables caching, epoch (for unix epoch) results in resource always being refetched, max sets the date to browser max value.

The ~image/ matches any image types.

More about nginx maps at http://nginx.org/en/docs/http/ngx_http_map_module.html.

Tags:

Nginx

Cache