Help with locations and regex

Francis Daly francis at daoine.org
Sat Oct 21 09:07:42 UTC 2017


On Fri, Oct 20, 2017 at 06:37:45PM -0400, anon59682 wrote:

Hi there,

> Location 1: the following paths should all load the requested file from
> /home/user/project/dist/ and fall back to /home/user/project/dist/index.html
> if the explicit filename was not found (ideally, without a redirect):
> 
> /admin
> /admin/
> /admin/favicon.ico
> /admin/foo
> /admin/foo/logo.png
> etc. - basically, anything beginning with /admin/ or /admin itself (but not
> /admin123)

That sounds like "location ^~ /admin/ {}", possibly with an extra
"location = /admin {}".

> Location 2: the root path should proxy_pass to a process running on another
> port. This is separate from location 3 because it has different location
> settings (such as auth).

"location = / {}".

> Location 3: all first-level paths off the root should proxy_pass to the
> process on the other port, for example:
> 
> /foo
> /bar123

"location ~ ^/[^/]*$ {}"

> /foo/baz # this would NOT be proxy passed, it can just fall through and 404
> or whatever

"location / {}"

> === End of Requirements ===
> 
> So far, the closest I have come is a situation where location 2 and 3 are
> working, but location 1 only partially works. In my current configuration
> for location 1, it will accept anything beginning with /admin (including
> /admin123) and it will 301 redirect /admin to /admin/ (note the trailing
> slash). Here is that config:
> 
> server {
>     listen 80 default_server;
>     server_name my.domain;
>     root /home/user/project/dist;
>     index index.html;
> 
>     # Location 1
>     location ^~ /admin {
>         alias /home/user/project/dist;
>         try_files $uri $uri/ /admin/index.html;
>     }

Make that be "location ^~ /admin/" and "alias /home/user/project/dist/"
(extra / on the end of both).

I'm not certain what you mean by the combination of "ideally, without a
redirect" and the suggestion that a request for "/admin/foo" (a directory)
does what you want, because I think (without testing) that the latter
does a redirect.

Possibly you want

  location = /admin { return 301 /admin/; }

or possibly

  location = /admin { alias /home/user/project/dist/index.html; }

If you don't want any redirect, and you are happy that the content
of the url /admin/index.html makes sense everywhere in the hierarchy,
use the second one above and remove the "$uri/" from the try_files.

>     # Location 3
>     location ~ /([^\/]+)$ {

/foo/baz matches this location. Add "^" to the start of the regex to avoid that.

>         # other stuff omitted for brevity
>         proxy_pass http://127.0.0.1:8080;
>     }
> }
> 
> I thought I should be able to use ^/admin(?:/.*)?$ for the location 1 match,

Right now, your location 1 is not a regex. I think that it is simplest
to keep it that way.

(If you really wanted just one location{}, you would want "starts with
/admin, then is followed by / or end-of-string".)

> I assume that's because I shouldn't be using alias and/or the try_files
> directive is wrong when using that regex, but I haven't been able to find
> the magic combination.

"alias" in a regex location is not the same as "alias" in a prefix location.

Also, there is a bug with alias and try_files and the fallback value
which you might be hitting, but if you see the expected response then
I guess it works for you.

	f
-- 
Francis Daly        francis at daoine.org


More information about the nginx mailing list