1

I have a next js app which I deployed on port 3000 and set the proxy 3000 on nginx.

Now I have my custom Node js Backend server which I want to run on the same server on different port 5000.

I setup the nginx like this

location / {
        proxy_http_version 1.1;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://localhost:3000;
    }
location ^~ /api {
        proxy_http_version 1.1;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass    http://localhost:5000;
            
        }

I have no issue with accessing the app on example.com. I setup the location /api for connecting the server.js / api fetching.

when I fetching like this

axios.get(example.com/api)

its returning error -- Cannot GET /api/

but when I set the nginx location proxy like this

proxy_pass    http://localhost:5000/;

with a forwar slash, its working and axios is fetching the data successfully.

But whenever I am trying to fetching another route from the server.js file like

axios.get(example.com/api/credential)

Its showing error again like this

Cannot GET //credential

Returning with double slash // credential

the only '/' route working from the server.js by fetching example.com/api

without the forward slash on proxy, its returning error. can not GET /api or can not GET api/credential

please help. Thanks in advance.

Update

I fixed with the Ivan's answer. Now I have new issue with that config. I am using socket.io beside the axios. So whenever I am trying to connect through socket.io my client socket code is ..

import io from "socket.io-client";
const socket = io("https://example.com/api");

and server socket config is ..

const io = require("socket.io")(server, {
  cors: {
    origin: "*",
  },
});

Now when the page loads, the console is logging..

GET https://example.com/socket.io?EIO=4&transport=polling&t=O4UTf4l 404 (Not Found)

please help.

1 Answers1

1

Generally, you should always prefer

location /prefix/ {
    ...
}

over the

location /prefix {
    ...
}

unless you are proxying a single API endpoint rather than a whole API (or another web app). When you use an URI prefix with the proxy_pass directive (that is, proxy_pass http://localhost:5000/; rather than proxy_pass http://localhost:5000;, the trailing slash counts as an URI prefix here), nginx will strip the prefix specified in location directive from your request URI and prepend it with the prefix specified in proxy_pass. Use

location ^~ /api/ {
    ...
    proxy_pass http://localhost:5000/;
}

and your /api/credential request URI will be correctly passed to your upstream as /credential.

Ivan Shatsky
  • 2,726
  • 2
  • 7
  • 19
  • Hi Ivan. Thanks for your answer. I helpd me and you saved my day. Now I have new issu with the socket.io. Please see the updated question. – Irfan Habib Jun 01 '22 at 08:56
  • I think you should use some different prefix for the websocket communications, e.g. `/ws` rather than mix it with the `/api` calls. You also should proxy WebSocket connections in a [special way](http://nginx.org/en/docs/http/websocket.html), however you already did it in your config. Unfortunately `socket.io` isn't the area of my competence, consider asking this as a separate question, maybe StackOverflow will be a more appropriate site to do it. – Ivan Shatsky Jun 01 '22 at 09:57