Score:0

nginx reverse proxy not working when multiple ports defined for REST api

bd flag

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.

Score:0
gr flag

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.

Irfan Habib avatar
bd flag
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.
Ivan Shatsky avatar
gr flag
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.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.