Search code examples
dockernginxreverse-proxy

Why is my Nginx reverse proxy doing a 301 redirect instead of proxying?


I have an Nginx reverse proxy inside a docker container, which listens to port 3000 and is exposed to 3002: docker run -p "3002:3000" ....

The idea is that this reverse proxy will proxy /my-app to the instance running in my laptop on port 8080; and /my-app/api to the cloud instance, in https://my-domain.

Here's the configuration:

upstream my-laptop {
  server host.docker.internal:8080; # this is a magic hostname for the laptop's IP address.
  keepalive 64;
}

upstream cloud {
  server my-domain.com:443;
  keepalive 64;
}

server {
    listen       3000;

    include ssl/ssl-certs.conf;
    include ssl/ssl-params.conf;

    location /my-app {
        proxy_pass http://my-laptop;
        proxy_set_header Host            $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location /my-app/api {
        proxy_pass https://cloud;
        proxy_set_header Host            $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    ...
}

The issues are:

  1. when I hit https://localhost:3002/my-app I get a 301 response to /my-app/ (trailing slash). I don't know why is that. The local app instance is shown in the browser, so I guess I can let it slide for the moment?
  2. when I hit https://localhost:3002/my-app/api/students, I get a 301 response to https://cloud/my-app/api/students. This causes CORS issues, of course, and the endpoint doesn't return data.

Now, I have configured reverse proxies a couple of times, so I am completely shocked that I'm not seeing what's wrong, this is not my first time.

I have tried tweaking with the upstreams, the proxy_set_headers, compared with another reverse proxy that I have for a different app; I'm out of ideas.

What am I doing wrong?


Solution

  • The problem was my Host header in the cloud upstream, I had

    proxy_set_header Host $http_host;
    

    But it needed to be

    proxy_set_header Host my-domain.com;