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 have following server configuration:

server {
    listen       80;
    server_name  mysite.proj;

    location / {
        root /path/to/mysite.proj/www;
        index index.php index.html index.htm;
    }

    access_log /path/to/mysite.proj/data/logs/access.log;
    error_log  /path/to/mysite.proj/data/logs/error.log;

    if (!-e $request_filename) {
        rewrite ^(.+)$ /index.php last;
    }

    location ~ \.php$ {
        root           /path/to/mysite.proj/www;
        fastcgi_pass   127.0.0.1:8081;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /path/to/mysite.proj/www$fastcgi_script_name;
        include        fastcgi_params;
    }
}

server {
    listen 80;
    server_name www.mysite.proj;
    rewrite ^/(.*) http://mysite.proj/$1 permanent;
}

It works fine, every url is rewritten to index.php. But in same time every stylesheet url, every javascript url, every image url is rewriten as well. How to write rewrite rule to not rewrite urls for css, js, images files?

share|improve this question
    
Use try_files instead of your if {} block: try_files $uri $uri/ /index.php; As a side note, I believe nginx uses -f instead of -e for checking the existence of a file. –  cyberx86 Oct 19 '11 at 19:01
    
doesn't work... anything else? –  Eugene Manuilov Oct 19 '11 at 19:37
    
Sorry, I ignored the file restrictions. Firstly, move the 'root' directive out of your location blocks (just good form). Now, if I understand right, you are trying to redirect ALL files and directories to index.php except for css, js, and images (which if they don't exist should throw a 404). Try: if (!-e $request_filename) { rewrite ^(.+)[^(css|js|gif|...)]$ /index.php last; } Not exactly elegant enough for me to submit it as an answer, though (through some combination of location and try_files, you should be able to do that without the if) –  cyberx86 Oct 19 '11 at 20:56
add comment

1 Answer

up vote 1 down vote accepted

You don't have a root set in the server context, which is where the if is, so it uses the default of <install prefix>/html. You should move the root to the server context and switch out the if for a try_files. Also, there's no reason to capture the request in the no-www redirect, as the original request is already stored in $request_uri.

server {
    listen 80;
    server_name www.mysite.proj;
    # Permanent redirect to no-www
    return 301 http://mysite.proj$request_uri;
}

server {
    listen 80;
    server_name mysite.proj;

    root /path/to/mysite.proj/www;
    index index.php index.html index.htm;

    access_log /path/to/mysite.proj/data/logs/access.log;
    error_log  /path/to/mysite.proj/data/logs/error.log;

    location / {
        # try_files does not preserve query string by default like rewrite
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        # If the requested file doesn't exist, and /index.php doesn't, return a 404
        try_files $uri /index.php =404;

        include        fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        fastcgi_pass   127.0.0.1:8081;
    }
}
share|improve this answer
    
Thanks for your help –  Eugene Manuilov Oct 20 '11 at 7:19
add comment

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.