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 just moved from apache to nginx and I'm struggling with some configuration settings that doesn't seem to work. I have these rules from my previous .htaccess file that I'm trying to convert to nginx rules:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(js|css)/([a-z0-9\.]+)\.(js|css)$ $1/index.php?hash=$2 [L,QSA]

RewriteCond %{REQUEST_URI} !\.(gif|jpe?g|s?html|css|js|cgi)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L,QSA]

As you can tell, this says that each file that do not exist but follow the specified pattern has to be served by a php script. No further processing. Then, for each file that are not static and does not exist on the disk, send them to the main index.php file.

I know how to serve static files directly and I know how to make the first rule. The thing that I don't know how to solve is having these both conditions work together. Here is what I have so far:

location / {
    try_files $uri $uri/ /index.php;
}

location /js/ { 
    rewrite ^/js/([a-z0-9.]+).js$ /js/index.php?hash=$1 break; 
} 

location /css/ { 
    rewrite ^/css/([a-z0-9.]+).css$ /css/index.php?hash=$1 break; 
}

# serve static files directly
location ~* \.(?:jpg|jpeg|gif|css|png|js|ico)$ {
    access_log        off;
    expires           30d;
    add_header Pragma public;  
    add_header Cache-Control "public"; 
} 

location ~ \.php$ {
    # basic settings for php files
}

As I said, if I leave all those three location directives enabled, static files will be served directly, but styles or js files that follow the specified pattern will return 404 error (as in they are not found at that specific location). If I comment the static files directive and enable the rewrite rules for css/js that have to be served by a script, static files inside css/js directories will not be served (a blank page is returned) but all other static files will be served normally.

I really don't know what to do anymore. I've spent hours looking up on the internet on how to solve this, but everything I tried didn't work.

share|improve this question

1 Answer 1

up vote 0 down vote accepted
+50

Solution:

location / {
    try_files $uri $uri/ /index.php;
}

# serve static files directly
location ~* \.(?:jpg|jpeg|gif|css|png|js|ico)$ {
    access_log        off;
    expires           30d;
    add_header Pragma public;
    add_header Cache-Control "public";
    try_files $uri @fallback;
}

location @fallback {
    rewrite ^/(js|css)/([a-z0-9.]+)\.(js|css)$ /$1/index.php?hash=$2;
}

location ~ \.php$ {
    # basic settings for php files
}
share|improve this answer
    
thanks, but it is not working. after I add this rules all the static files are sent to the php script, which is wrong. I need only files that do not exist and follow the specified pattern to be sent to the php script. everything else from those directories should be served directly. –  misterjinx Sep 9 '13 at 19:51
    
@misterjinx Answer updated. –  Changaco Sep 9 '13 at 20:06
    
still no luck, after I updated with this, the dynamic files are not found (404) and the regular files are served correctly. I really don't know how to make them work together :| –  misterjinx Sep 9 '13 at 20:55
    
@misterjinx What does nginx' error log say when you get 404 for the dynamic files ? –  Changaco Sep 10 '13 at 8:17
    
*1 open() "<path>" failed (2: No such file or directory) –  misterjinx Sep 12 '13 at 19:01

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.