Nginx reverse proxy + URL rewrite
Solution 1:
Any redirect to localhost doesn't make sense from a remote system (e.g. client's Web browser). So the rewrite flags permanent (301) or redirect (302) are not usable in your case.
Please try following setup using a transparent rewrite rule:
location /foo {
rewrite /foo/(.*) /$1 break;
proxy_pass http://localhost:3200;
proxy_redirect off;
proxy_set_header Host $host;
}
Use curl -i
to test your rewrites. A very subtle change to the rule can cause nginx to perform a redirect.
Solution 2:
Simple location prefix matching works for this without using a rewrite rule as long as you specify a URI in the proxy_pass directive:
location /foo {
proxy_pass http://localhost:3200/;
}
Notice the additional /
at the end of the proxy_pass
directive. NGINX will strip the matched prefix /foo
and pass the remainder to the backend server at the URI /
. Therefore, http://myserver:80/foo/bar
will post to the backend at http://localhost:3200/bar
.
From the NGINX docs on proxy_pass:
If the proxy_pass directive is specified with a URI, then when a request is passed to the server, the part of a normalized request URI matching the location is replaced by a URI specified in the directive:
Solution 3:
The absolute most correct way and best practice is usually as follows:
location /foo/ {
proxy_pass http://localhost:3200/; # note the trailing slash!
}
Note the dire importance of the trailing slash in
proxy_pass
, which automatically alters the$uri
variable to have the/foo/
on the front-end correspond with/
on the backend. No need for an explicitrewrite
directive.Additionally, note that the the trailing
/
in thelocation
is quite important as well — without it, you risk having weird-looking URLs on your site at one point (e.g., a working/fooen
in addition to/foo/en
).Additionally, the trailing
/
in thelocation
withproxy_pass
also ensures some special handling, as per the documentation of thelocation
directive, to effectively cause an implicitlocation = /foo {return 301 /foo/;}
as well.So, by defining a
location
with the trailing slash as above, you not only ensure that slash-less suffix URLs like/fooen
won't be valid, but also that a/foo
without a trailing slash will continue to work as well.
Reference documentation:
- http://nginx.org/r/location
- http://nginx.org/r/proxy_pass
Solution 4:
try
location /foo {
proxy_pass http://localhost:3200/;
....
or
location ^~ /foo {
proxy_pass http://localhost:3200/;
....