location / {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    if (-f $request_filename) {
        access_log off;
        expires 30d;
        break;
        }

    if (!-f $request_filename) {
        proxy_pass http://127.0.0.1:8080; # backend server listening
        break;
        }
    }

Above will serve all existing files directly using Nginx (e.g. Nginx just displays PHP source code), otherwise forward a request to Apache. I need to exclude *.php files from the rule so that requests for *.php are also passed to Apache and processed.

I want Nginx to handle all static files and Apache to process all dynamic stuff.

EDIT: There is white list approach, but it is not very elegant, See all those extensions, I don't want this.

location ~* ^.+.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$ {
    access_log off;
    expires 30d;
    }
location / {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
    }

EDIT 2: On newer versions of Nginx use try_files instead http://wiki.nginx.org/HttpCoreModule#try_files

m0meni's user avatar

m0meni

16.5k18 gold badges87 silver badges148 bronze badges

asked May 15, 2009 at 14:24

fmalina's user avatar

fmalinafmalina

6,3104 gold badges39 silver badges47 bronze badges

1

Use try_files and named location block ('@apachesite'). This will remove unnecessary regex match and if block. More efficient.

location / {
    root /path/to/root/of/static/files;
    try_files $uri $uri/ @apachesite;

    expires max;
    access_log off;
}

location @apachesite {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
}

Update: The assumption of this config is that there doesn't exist any php script under /path/to/root/of/static/files. This is common in most modern php frameworks. In case your legacy php projects have both php scripts and static files mixed in the same folder, you may have to whitelist all of the file types you want nginx to serve.

answered Mar 17, 2013 at 23:27

Chuan Ma's user avatar

Chuan MaChuan Ma

9,9242 gold badges48 silver badges37 bronze badges

7

Try this:

location / {
    root /path/to/root;
    expires 30d;
    access_log off;
}

location ~* ^.*\.php$ {
    if (!-f $request_filename) {
        return 404;
    }
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
}

Hopefully it works. Regular expressions have higher priority than plain strings, so all requests ending in .php should be forwared to Apache if only a corresponding .php file exists. Rest will be handled as static files. The actual algorithm of evaluating location is here.

answered May 16, 2009 at 21:02

Jasiu's user avatar

JasiuJasiu

2,7243 gold badges27 silver badges27 bronze badges

0

If you use mod_rewrite to hide the extension of your scripts, or if you just like pretty URLs that end in /, then you might want to approach this from the other direction. Tell nginx to let anything with a non-static extension to go through to apache. For example:

location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm)$
{
    root   /path/to/static-content;
}

location ~* ^!.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm)$ {
    if (!-f $request_filename) {
        return 404;
    }
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
}

I found the first part of this snippet over at: http://code.google.com/p/scalr/wiki/NginxStatic

answered Feb 13, 2012 at 19:37

lo_fye's user avatar

lo_fyelo_fye

6,8605 gold badges34 silver badges49 bronze badges

1

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.