Nginx is running on port 80, and I'm using it to reverse proxy URLs with path /foo
to port 3200
this way:
location /foo {
proxy_pass http://localhost:3200;
proxy_redirect off;
proxy_set_header Host $host;
}
This works fine, but I have an application on port 3200
, for which I don't want the initial /foo
to be sent to. That is - when I access http://localhost/foo/bar
, I want only /bar
to be the path as received by the app. So I tried adding this line to the location block above:
rewrite ^(.*)foo(.*)$ http://localhost:3200/$2 permanent;
This causes 302 redirect (change in URL), but I want 301. What should I do?
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:
Use
curl -i
to test your rewrites. A very subtle change to the rule can cause nginx to perform a redirect.Simple location prefix matching works for this without using a rewrite rule as long as you specify a URI in the proxy_pass directive:
Notice the additional
/
at the end of theproxy_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 athttp://localhost:3200/bar
.From the NGINX docs on proxy_pass:
The absolute most correct way and best practice is usually as follows:
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:
try
or
@Terabuck Sorry for not replying no rep yet.
You should not use localhost because you are depending on the fact that application is running on a server with a hosts file. local host is only a default translation to 127.0.0.1. There is nothing stating that you must have this hosts files. It's just very common to have one.
Having a loopback interface is again another common thing to depend on but you are still dependent on the loopback interface on the networking stack. It's a rare case to not have these two. If you ever worry about this. At least on unix/linux you have the option for sockets. This will eliminate the need to for the network stack to reach the localhost. Use caution with this approach as there are a few factors that will come into place on the host OS. Such as the number of open files etc.