Nginx reverse proxy doesn't allow POST requests - node.js

I have a server on which I serve my 2 Node js apps, one on https://example.com/app1 and another one on https://example.com/app2. I managed to get this working by using nginx reverse proxy, setting each app to run on one port, and redirecting clients to each port based on the above addresses.
However, I'm facing this problem now where I can't save any POST requests to my MongoDB. Specifically, if I make POST request from https://example.com/app1 I get 405; if I send POST request from https://example.com:3000 everything is fine and data is saved in DB. Just to make it clear, port 3000 is the port on which app1 is running.
Can someone help me and point out to me what am I missing here? I feel like the issue here is that the app is working on port 3000 and is shown on port 80, but the data from port 80 doesn't get back to port 3000?
My reverse proxy code:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name mysubdomain.domain.com www.mysubdomain.domain.com;
location /app1 {
rewrite ^/app1/(.*)$ /$1 break;
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://myIPaddress:3000;
}
}

Related

Nginx reverse proxy to NodeJS App causing 502 bad gateway error

I am setting up nginx so that I can access my API built using express through a url like - example.com/api
Here is my nginx config
upstream appfrontend {
server localhost:9008 fail_timeout=0;
}
upstream api {
server localhost:3001;
}
server {
listen 80;
listen [::]:80;
server_name hospoline.com www.hospoline.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
listen [::]:443;
server_name example.com; # replace this with your domain
root /var/www/html/example-certbot-webroot;
# The public and private parts of the certificate are linked here
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location /.well-known {
root /var/www/html/example;
}
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://appfrontend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 900s;
}
location /api {
proxy_pass http://api;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
When I visit my site example.com the front end loads perfectly.
When I visit example.com/api/fetch_doctors, I get a 502 bad gateway error.
My API is working fine in localhost. When I send a request to localhost:3001 on my local computer, I get the list of doctors.
Both my front end server and backend server are run using forever.
I am really lost and breaking my head about this for one full day. I have no idea where I'm going wrong. Any help in the right direction would be great! Thank you all!

make nginx redirect to random port

I'm working on setting up a load balancer for my website. I want to do it manually so that I have full control over how the requests are rerouted. Im using AWS EBS to load balance between 2 ec2 instances, and that works fine. Each ec2 instance uses nginx as a reverse proxy for nodejs.
Currently, I only have 1 node app running on each server, but Ideally I would like to have 4 node apps on each server (1 for each core).
I was thinking that a really easy way to manage this would be to allow nginx to pick a random port between 8081, and 8084 and redirect to one of the apps. In theory this way I would be balancing the load as evenly as possible.
Currently this is my nginx reverse proxy set up:
server {
client_max_body_size 200M;
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
location / {
client_max_body_size 200M;
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Real-User-Agent $http_user_agent;
proxy_set_header Connection 'upgrade';
proxy_set_header X-serv-ip 'my.server.ip';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Basically, my question boils down to if there's some way to make a variable like $rand_port and every time a request is made, $rand_port is set to 8081, 8082, 8083, or 8084, and then in my proxy_pass I could do something like:
proxy_pass http://localhost:{$rand_port} #not sure if the syntax is right.
Is there anything that lets me do something like this, or otherwise what other solutions are there?
nginx load balancing allows you to determine the algorithm ... if you just need each server to be equally loaded use this
upstream myproject {
server 127.0.0.1:8081;
server 127.0.0.1:8082;
server 127.0.0.1:8083;
server 127.0.0.1:8084;
}
server {
client_max_body_size 200M;
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
location / {
client_max_body_size 200M;
proxy_pass http://myproject;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Real-User-Agent $http_user_agent;
proxy_set_header Connection 'upgrade';
proxy_set_header X-serv-ip 'my.server.ip';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}

How to configure nginx to redirect to same app from multiple ports?

I have a node.js app and I am running nginx as a reverse proxy server. I want to access the same app through multiple ways.
Let the ip address of machine be 12.16.12.113.
Then I want the same app to be accessible through:
12.16.12.113:3000
test.example.com
I have 2 Configuration files for nginx in sites-available directory:
file1:
server {
listen 80;
server_name test.example.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
file2:
server {
listen 3000;
server_name default_server;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
The problem is that if I link both the files in sites-enabled directory, then only the app is accessible only through 12.16.12.113:3000. If I remove file2, then it is accessible through test.example.com.
But I want both the methods to work.
Edit 1:
Based on suggestion from this answer, I did the following test:
It appears that nginx is not listening to port 80. Why is this happening?
The are few ways to achieve that.
You can make your Node app listen on 12.16.12.113:3000 instead of on localhost:3000 and then you will need nginx only for port 80.
You can make your Node app listen on localhost:3000 (but only on localhost) and then proxy 12.16.12.113:3000 and port 80 by nginx.
You can make your Node app listen on localhost:4000 or 0.0.0.0:4000 on any interface and use nginx to proxy requests to port 80 and 3000.
But you will not be able to make them both listen on the same port and the same interface without problems.
This is the only advice that could be given considering the fact that you didn't include any code example of how your Node app is binding to the ports, which would be the only relevant information here.

ignore nginx port to add in url? When i change nginx port

I want to use nginx on different port. If i am running nginx on default port(80) and trying to use by the url (100.100.7.60) this is working fine.
server {
listen 80;
server_name 100.100.7.60;
location / {
proxy_pass http://100.100.7.60:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
But when i am changing nginx port 80 to 8080 or to any port. If now i am trying by (100.100.7.60). I am unable to run node.js application. Now if i want to run application my url should be like (100.100.7.60:8080).
server {
listen 8080;
server_name 100.100.7.60;
location / {
proxy_pass http://100.100.7.60:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Can anyone explain me what is problem? I want to change port number. But i do not want to add (:8080) in url. I want to make same url after changing port number
If you want to listen on a different port, you cannot exclude the port number from the URL. When you enter 100.100.7.60 into a browser, the protocol is HTTP and the port is 80 by default.
There is a (very bad) workaround to this:
server {
listen 80;
server_name 100.100.7.60;
return 301 http://100.100.7.60:8080;
}
This will redirect ALL traffic on port 80 to port 8080, which is (I assume) not what you want.
Instead, you should configure your DNS to point to this server using a subdomain eg myapp.example.com and then listen on 80 port with that server name to serve your app.

Hide port 8383 in glassfish 3.1.2

I am running Glassfish 3.1.2 on Linux 6 server to deploy Oracle Apex.
I want to to hide port 8383 from url (current url say : https://sd1.domain.com:8383/apex)
80 and 443 port are already assigned for another service.
So, how can I hide port 8383 from URL.
A TCP connection is between two ip:port pairs. In case the server's port is a common one like 80/443, most browsers don't display it.
You can use a reverse proxy on port 80, that classifies incoming HTTP traffic.
It could check the subdomain in the HTTP header and then forward traffic to one of the two web servers (which both listen on dedicated ports).
With nginx the config file could look like this:
server {
server_name sd1.domain.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:8383;
}
}
server {
server_name www.domain.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:8080;
}
}

Resources