nginx proxy pass redirects ignore port

So I'm setting up a virtual path when pointing at a node.js app in my nginx conf. the relevant section looks like so:

location /app {
  rewrite /app/(.*) /$1 break;
  proxy_pass http://localhost:3000;
  proxy_redirect off;
  proxy_set_header Host $host;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

Works great, except that when my node.js app (an express app) calls a redirect.

As an example, the dev box is running nginx on port 8080, and so the url's to the root of the node app looks like:

http://localhost:8080/app

When I call a redirect to '/app' from node, the actual redirect goes to:

http://localhost/app


Solution 1:

The problem is that the Node.js application is not issuing the redirect correctly. You may be able to use proxy_redirect to correct this in nginx:

proxy_redirect http://localhost/ http://localhost:8080/;

Solution 2:

I just had to solve the same problem with Jenkins running behind nginx. What did it for me was to include the server port into the Host header that's being sent to Jenkins:

proxy_set_header Host $host:$server_port;

Hope that helps.

Solution 3:

Per the conversation on this question, the proper resolution is to adjust the proxy's Host header directive.

Change this:

proxy_set_header Host $host;

To this:

proxy_set_header Host $http_host;

$http_host holds the value as specified in HTTP HOST header, which includes the port. Redirects should pick up the custom port without further customization to OP's setup.

These answers (same ticket) elaborate further:

  • https://serverfault.com/a/407983/298623
  • https://serverfault.com/a/731985/298623