views:

1741

answers:

3

I can't seem to get nginx to set expires headers on my static assets in my Rails app.

My app is deployed using Phusion Passenger & nginx.

Below is the related section of my nginx config file

server {
        listen  80;
        server_name my.domain.tld;
        root /home/deploy/my.domain.tld/current/public;
        passenger_enabled on;
        access_log off;

        location ~* \.(ico|css|js|gif|jp?g|png)\?[0-9]+$ {
                expires max;
                break;
        }

        if (-f $document_root/system/maintenance.html) {
                rewrite ^(.*)$ /system/maintenance.html break;
        }
}

I'm not sure why its not setting expires headers on my static assets ( e.g. /images/foo.png?123456 )

I'm not sure if it has something to do with passenger or if my location regexp just isnt catching it

A: 

Maybe this will help:

location ~* ^.*\.(ico|css|js|gif|jp?g|png)\?[0-9]+$ {

Also read how Nginx evaluates location. Are you sure you don't have any other string location in your config file that matches your static resources before your regexp location does?

BTW, consider using try_files instead of if (-f $document_root/...).

Jasiu
no, that is my current config file. there are no other location directives.I'll try your regexp and see if it sets the headers.Also, I'm not sure why you recommend using try_files instead of the -f flag. Why / how is try_files and improvement in this case?
cpjolicoeur
I'm not really sure, but Igor (the author) always recommends using try_files when people ask about rewrites on Nginx mailing list. The "if (-f ...)" directive may be parsed slower, but I've never made any experiment to try that.
Jasiu
+2  A: 

So I ended up finding the solution. My regexp was a bit off, as I wasn't taking into account the possibility that the ?timestamp didn't exist.

This regexp worked for me.

location ~* \.(ico|css|js|gif|jp?g|png)(\?[0-9]+)?$ {
cpjolicoeur
A: 

Just wanted to point out that making the timestamp optional is a bad idea – if it's not included, then setting expires max is wrong as there would be no way of refreshing the file.

Also, the location directive in Nginx can't see the query string, so the solution posted here never matches the 'optional' timestamp.

A proper solution (ie one that sends the maximum expires only when the file was requested with a timestamp) would be:

location ~* \.(js|css|png|jpg)$ {
  if ($query_string ~ "^[0-9]+$") {
    expires max;
    break;
  }
}

If the timestamp is not specified, then you rely on Last-Modified and ETag, which are handled automatically by Nginx.

djanowski