How can I create a location in nginx that works with AND without a trailing slash?
Solution 1:
The better solution:
location ~ ^/phpmyadmin(?:/(.*))?$ {
alias /home/phpmyadmin/$1;
}
Ensure that server has permissions to /home/phpmyadmin
first.
Explanation of difference with accepted answer:
It's all about regular expressions.
First of all, the ^
char means that you want to match from beginning of string and not somewhere in the middle. The $
at the end means matching to the end of the string.
The (?:)
means non-capturing group - we don't want it in the capturing results, but we want to simple group some chars. We group it like this, because we want the /
char to be a nonsignificant part of the child path, and not a significant part of the parent path.
Solution 2:
It might be in the regular expression that you're using --
location ~ ^/phpmyadmin/(.*)$
The above will match /phpmyadmin/, /phpmyadmin/anything/else/here, but it won't match /phpmyadmin because the regular expression includes the trailing slash.
You probably want something like this:
location ~ /phpmyadmin/?(.*)$ {
alias /home/phpmyadmin/$1;
}
The question mark is a regular expression quantifier and should tell nginx to match zero or one of the previous character (the slash).
Warning: The community seen this solution, as is, as a possible security risk
Solution 3:
Why wouldn't you just use
location /phpmyadmin {
alias /home/phpmyadmin;
}
?
Solution 4:
I know this is an old question, but for anybody that ends up here via Google, I solved it the following way (variation of @kbec's one, which was quite good):
location ~ ^/foo(/.*)?$ {
proxy_pass http://$backend$1$is_args$args
}
This will capture any variation of /foo
and redirect it to /bar
on another url (including parameters). I am showing it with a proxy_pass
directive but it would also work with alias
.
/foo
->/bar
/foo/
->/bar/
/foo/sub
->/bar/sub
/foo/sub1/sub2/?param=value
->/bar/sub1/sub2/?param=value
It works because $1
will optionally capture the subresources plus the leading slash, so it won't capture things like /fooextra/
. It will also redirect a present or non-present ending slash properly.
Solution 5:
This redirect will only rewrite URLs with and without the trailing slash. Anything that comes after the slash won't be overwritten.
domain.com/location => redirected to domain.com/new/location
domain.com/location => redirected to domain.com/new/location
domain.com/location/other => not redirected
server {
# 301 URL Redirect
rewrite ^/location/?$ /new/location permanent;
}