Config help - Reverse Proxy for Virtual Directories

I’m trying to get nginx to do the following (among other things):

If the URL matches /ObjJob/YYY
if exists /var/www/phrogz.net/ObjJob/public/YYY, serve it statically
otherwise proxy it to http://localhost:9901/YYY #no ObjJob

If the URL matches /SubSite2/ZZZ
if exists /var/www/phrogz.net/SubSite2/public/ZZZ, serve it statically
otherwise proxy it to http://localhost:9902/ZZZ #no SubSite2

If the URL doesn’t match any of the above (/VVV) then
if exists /var/www/phrogz.net/Phrogz/public/VVV, serve it statically
otherwise proxy it to http://localhost:9900/VVV

My current config can be seen here:
http://pastie.org/394796

The following URLs work as desired:
http://localhost/static.css # serves from /var/www/phrogz.net/
Phrogz/public/static.css
http://localhost/ # proxies to :9900 properly
http://localhost/dynamic # proxies to :9900 properly

http://localhost/ObjJob/common.css # serves from /var/www/
phrogz.net/ObjJob/public/common.css

The following 2 ‘work’, but leave “ObjJob” at the front

of the path on the far side of the proxy; ideally I would like

the receiving process to think it’s the only application around

with no knowledge of the “ObjJob” prefix.

http://localhost/ObjJob # proxies to :9901 properly
http://localhost/ObjJob/ # proxies to :9901 properly

My main problem, however, is that this fails:
http://localhost/ObjJob/dynamic

I get an nginx 404, with this in the error log:
open() “/var/www/phrogz.net/ObjJob/public/languages” failed (2: No
such file or directory), client: 127.0.0.1, server: localhost,
request: “GET /ObjJob/languages HTTP/1.1”, host: “localhost”

How can I fix my configuration to get this to work?

Thanks in advance for any help.

Let me try this again, more tersely:

Why does this (pared down) config…
http://pastie.org/395896
…give me a 404 when I use a URL like…
http://localhost/ObjJob/foo
…instead of proxying to port 9901 as desired?

What’s the right way to set up a virtual directory like this?

The only ‘fix’ I’ve found so far is to comment out lines 29 and 32,
causing all static files to be proxied and served by the proxy app
instead.

Perhaps the new try_file directive and an internal backend are what you
need. I’m still in 0.6.x land on my production boxes, but I think it is
something like this (from igor’s docs):

location / {
try_files /system/maintenance.html
$uri $uri/index.html $uri.html
@mongrel;
}

location @mongrel {
proxy_pass http://mongrel;
}

This will try the given $uri, index.html as subdirectory, the uri as
HTML
file, and finally resolve to the @mongrel backend. If you are using
0.6.x
or if that doesn’t work, you can always use the old school 404
redirector
like so:

location / {
error_page 404 = @mongrel;
}

location @mongrel {
proxy_pass http://mongrel;
}

The rest of the magic is up to you (I think you have it anyway).

  • Merlin

On Thu, Feb 19, 2009 at 10:52:07PM -0700, Gavin K. wrote:

http://localhost/ # proxies to :9900 properly
http://localhost/ObjJob/ # proxies to :9901 properly

My main problem, however, is that this fails:
http://localhost/ObjJob/dynamic

I get an nginx 404, with this in the error log:
open() “/var/www/phrogz.net/ObjJob/public/languages” failed (2: No
such file or directory), client: 127.0.0.1, server: localhost,
request: “GET /ObjJob/languages HTTP/1.1”, host: “localhost”

How can I fix my configuration to get this to work?

server {
    listen       80;
    server_name  localhost;

    access_log  logs/phrogz_access.log main;

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;

    location / {
        root /var/www/phrogz.net/Phrogz/public;
        error_page  404 = @9900;
    }

    location /ObjJob {
        alias /var/www/phrogz.net/ObjJob/public;
        error_page  404 = @9901;
    }

    location /SubSite2 {
        alias /var/www/phrogz.net/ObjJob/public;
        error_page  404 = @9902;
    }

    location @9900 {
        proxy_pass http://localhost:9900;
    }

    location @9901 {
        proxy_pass http://localhost:9901;
    }

    location @9902 {
        proxy_pass http://localhost:9902;
    }

    location /js {
        root /var/www/phrogz.net/;
        autoindex  on;
    }

    location /svg {
        root /var/www/phrogz.net/;
        autoindex  on;
    }

}

On Fri, Feb 20, 2009 at 10:17:17PM -0700, Gavin K. wrote:

Let me try this again, more tersely:

Why does this (pared down) config…
http://pastie.org/395896
…give me a 404 when I use a URL like…
http://localhost/ObjJob/foo
…instead of proxying to port 9901 as desired?

location ^~ /ObjJob {
  root /var/www/phrogz.net/ObjJob/public/;
  rewrite ^/ObjJob(/.+) $1 break;
  • rewrite ^/ObjJob(/.+) $1 break;
    
  • rewrite ^/ObjJob(/.+) $1;
    

as the “break” stops script execution and script does not run next
"if"s:

  if (-f $request_filename) {
    break;
  }
  if (!-f $request_filename) {
    proxy_pass http://localhost:9901;
    break;
  }
}

What’s the right way to set up a virtual directory like this?

No. The right way is

locaiton /ObjJob/ {
    alias /var/www/phrogz.net/ObjJob/public/;
    error_page  404 = @9901;
}

location @9901 {
    proxy_pass http://localhost:9901;
}

or if you use modern try_files:

locaiton /ObjJob/ {
    alias /var/www/phrogz.net/ObjJob/public/;
    try_files  $uri  @9901;
}

location @9901 {
    proxy_pass http://localhost:9901;
}