1

I need Nginx to serve a file relative from document root if it exists, then fallback to an upstream server if it doesn't. This can be accomplished with something like:

server {
    listen       80;
    server_name  localhost;

    location / {
        root /var/www/nginx/;
        try_files $uri @my_upstream;
    }

    location @my_upstream {
        internal;
        proxy_pass  http://127.0.0.1:8000;
    }
}

Fair enough. The problem is, my upstream is not serving the contents of URI directly, but instead, returning X-Accel-Redirect with a location relative to document root (it generates this file on-the-fly):

% curl -I http://127.0.0.1:8000/animals/kitten.jpg__100x100__crop.jpg
HTTP/1.0 200 OK
Date: Mon, 26 Nov 2012 20:58:25 GMT
Server: WSGIServer/0.1 Python/2.7.2
X-Accel-Redirect: animals/kitten.jpg__100x100__crop.jpg
Content-Type: text/html; charset=utf-8

Apparently, this should work. The problem though is that Nginx tries to serve this file from some internal default document root instead of using the one specified in the location block:

2012/11/26 18:44:55 [error] 824#0: *54 open() "/usr/local/Cellar/nginx/1.2.4/htmlanimals/kitten.jpg__100x100__crop.jpg" failed (2: No such file or directory), client: 127.0.0.1, server: localhost, request: "GET /animals/kitten.jpg__100x100__crop.jpg HTTP/1.1", upstream: "http://127.0.0.1:8000/animals/kitten.jpg__100x100__crop.jpg", host: "127.0.0.1:80"

How do I force Nginx to serve the file relative to the right document root? According to XSendfile documentation the returned path should be relative, so my upstream is doing the right thing.

2 Answers 2

1

You need to have your root directive under server, and not under location. This is one of the most common nginx configuration mistakes.

1
  • Thanks. I changed the root rule to the server block and it almost worked. I had to change my upstream to return an URI starting with a slash, apparently Nginx ignored the last slash in the root rule.
    – hcalves
    Nov 26, 2012 at 21:42
2

Your backend produces incorrect X-Accel-Redirect header: the path part of URI must start with / (see RFC 3986).

1
  • Yep, figured it out.
    – hcalves
    Nov 28, 2012 at 14:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .