Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I'm using nginx to server my static content, is there a way that I can set the expires headers for every file that meets a specific rule? For example can I set the expires header for all files that have an extension of '.css'?

share|improve this question

5 Answers 5

up vote 33 down vote accepted

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";
}
share|improve this answer
2  
All my static files were not found after adding that. –  Pineapple Under the Sea May 31 '12 at 0:45
    
@JackSpairow: I can't really explain why that happened, as It has always worked for me. Are you running Nginx missing the add_header providing module? This kind of thing really is limited in scope, you sure another deceleration is not a problem in combination? –  TechZilla May 31 '12 at 17:26
4  
Probably another block had definition for the static files with a root set, in that case you should add the directives to that block. (I know this is 2y late, but for future citizens) –  aularon Jul 5 at 23:36
    
I personally appreciate clarifications, especially for future searchers because they often show up long after the original post. +1 :P –  TechZilla Jul 21 at 18:14
server {
    ...

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

The location directive

The expires directive

share|improve this answer

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;
}
share|improve this answer
1  
I would use the root directive only in the server {} block, when using it in sub locations it leads to unexpected consequences. You don't need the break; either, as you're not in an if {} block –  Dave Cheney Jun 10 '09 at 10:47
    
You are right. Forgot to clean this up. Edited to reflect this. –  Jauder Ho Jun 11 '09 at 1:02

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;
}
share|improve this answer

If you have one place that is home to all your static files, something like this will do...

 location /static {
            your/location/to/static/files/static;
            expires 30d;
            add_header Cache-Control "public";
    }

The accepted answer caused nginx to not find any of my static files. Not really sure why, but this is a simple alternative.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.