Serve index.html file if exists try_files + proxy_pass?

Francis Daly francis at
Mon May 1 11:18:49 UTC 2017

On Sun, Apr 30, 2017 at 10:44:21AM +0000, Lucas Rolff wrote:

Hi there,

> I have a small scenario where I have a backend (s3 compatible storage), which by default generates a directory listing overview of the files stored.
> I want to be able to serve an "index.html" file if the file exists, else just proxy_pass as normally.

I think that it will be very useful to be utterly clear on the distinction
between a file and a url here. If you can describe what you want to happen
in exact terms, there is a much better chance that the configuration
you want will be clear.

A file is a thing available on the local nginx filesystem. Its full name
will be some thing like /usr/local/nginx/html/one/two.

A url is a thing available by proxy_pass:ing to a http server. (That's
good enough for these purposes.) Its full name will be something like

(The http server on upstream may have a direct mapping between urls it
receives and files it knows about; that's because those files are on
upstream's local filesystem. Similarly, nginx receives requests which
are urls, and it may map them to files or to other urls. This can get
confusing. That's why it is useful to be explicit.)

> My nginx config for somewhat reason doesn't work – or maybe it's because I misunderstand how try_files actually work.

try_files checks for the existence of a file. In the common case, the full
name of the file that it checks is the concatenation of $document_root
with the argument to try_files.

> So I have URLs such as:
> When I request these URL's I want nginx to check if index.html exists in the directory (it's an actual file on the filesystem) - if it does, serve this one, else go to @minio location.

Can you be specific here, with a worked example?

The request to nginx is for /one/two/. What do you want nginx to do? (If
you mention the word "file", please use the full name of the file that
you are interested in.)

Then, a separate request to nginx is for /one/three. Same question.

> For any other file within the directory, I will just go to @minio location so if I request unicorn.png it should go in @minio location as well.
> Is there any decent (non-evil) way of doing this?
> I assume I have to define the root directive to make try_files work, but what would I actually have to define, to make nginx use try_files for index.html *within* the specific bucket?

nginx does not know about buckets. It knows about incoming requests,
and it knows about files and directories.

I *suspect* that you can do what you want with one "location ~ /$"
inside your "location /"; but I'm not fully clear on what you want.

I also suspect that the correct solution is to just configure the
upstream http server to serve the contents of index.html if it exists,
when it gets a request ending in / -- presumably there's a reason why
that isn't done instead.

Good luck with it,

Francis Daly        francis at

More information about the nginx mailing list