Nginx upstream servers all go down when one of them shuts down - node.js

I'm trying to set up upstream servers with nginx. All run the same Node.js app on port 8080 with pm2. Here is the nginx default.conf of the main server
upstream backend {
ip_hash;
server localhost:8080;
server sv1_ip_address;
server sv2_ip_address;
}
server {
listen 443 ssl;
location / {
proxy_pass http://backend;
...
}
...
}
And on sv1 and sv2, I have the same default.conf as follows
server {
listen 80 default_server;
location / {
proxy_pass http://localhost:8080;
...
}
}
Now when I tried shutting down either sv1 or sv2 (using pm2 kill for Node or even reboot), all upstream servers went down and I receive a 500 error (?) when accessing the app by the domain name. So I thought there was something wrong with nginx on those secondary servers and I replaced upstream backend with this
upstream backend {
ip_hash;
server localhost:8080;
server sv1_ip_address:8080;
server sv2_ip_address:8080;
}
and now shutting down or rebooting were handled correctly (meaning nginx will route the requests to one of the living servers). Is this an expected behavior, or am I doing something wrong here? I don't think routing requests directly to port 8080 is a good idea though.

I donot know why you had to install nginx service on sv1 and sv2 servers.
When you reboot sv1 , sv2 servers, it should be enabling nginx first. Please check service nginx status is running or not once reboot is done.
And you kill node meaning application is down, so you got 500 error on nginx

Related

Nginx reverse proxy in docker for express.js server

In docker, I have a client facing server container, an api server container and a nginx container that is exposed outside at port 8000. After running api and client server container, I am running nginx container with has nginx.conf replaced with the following:
events {
}
http {
server {
listen 80;
location /api {
proxy_pass http://server:9002;
}
location / {
proxy_pass http://client:9001;
}
}
}
I can verify client server working properly through nginx by making request to http://localhost:8000 or http://localhost:8000/blah. But if I go to the URL http://localhost:8000/api, it redirects to http://localhost/api and fails to connect.
I verified that the server container is actually running by running it with a separate exposed port and it returns result on request as expected. How would I fix this ?
It might have been an environmental variable issue. I had PORT env var set on docker-compose.yml but not in Docekrfile, adding it solved the issue. Removing PORT env var from docker-compose.yml still works.

How to connect nginx to local mongodb

I've got nginx to run my (node.js/react) application on the server. But I can't seem to connect to the database.
In the nginx.conf file I've added the following inside http.
http {
...
server {
listen 80;
server_name localhost;
...}
...}
And above the http section I have the following,
stream {
server {
listen 4000;
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass stream_mongo_backend;
}
upstream stream_mongo_backend {
server 127.0.0.1:27017;
}
}
I start the nginx server, the application runs on localhost, opens up the login page but I can't login because it's still not connected to the database (mongodb).
I'm not sure if I've got my port numbers wrong or if I'm missing some configuration line inside nginx.conf.
EDIT: Ok, I had it wrong before. I wasn't supposed to connect to mongodb at this point. I was supposed to connect to the backend server of my application which would run at 4000. So now I've added a new location for /api/ inside http and proxied all requests to 4000. I still have one question though. I have to run my backend server separately for this to work. For the frontend I've created a folder and put all my build files in there so nginx starts up the webserver from there. Doing the same for the backend did not start up the server. Is there a way to get nginx to start the backend server as well?
Also can I get the frontend to run directly without the build files ? Like node would with npm start?
the port number is right. try to open up a mongo shell and see if you are able to access a mongo instance. if not, you will need to run sudo service mongodb start to start it up.
Guess it's knida late but you don't need to setup nginx for your backend to connect local mongodb.
And you need to run the frontend and backend server first by yarn start, node run or something like that if you want to run it without build files.
And then bypass the calls from 80 port to the local host servers.
For example, your FE run at 3000 port, BE run at 5000 port.
Then your nginx should be:
http {
...
server {
listen 80;
server_name localhost;
location /api/ {
proxy_pass localhost:5000;
}
location / {
proxy_pass localhost:3000;
}
...}
...}

Ngnix configuration load balancer node js server

I have developed a Rest API with node js on a machine with ubuntu server 16.04 and on another machine with same SO I have installed Nginx as a reverse proxy. Now I would like to set my Rest API in load balancing deploying my application on two servers.
How can I configure Nginx as a load balancer with to server that exposes the same node js application?
edit your /etc/nginx/sites-available/default according to DigitalOcean such as
upstream backend_hosts {
server host1.example.com;
server host2.example.com;
server host3.example.com;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_hosts;
}
}

ExpressJS Server - respond to host header with shared port

Lets say I have corporatewebsite.com listening on port 80. Which is an appache / WordPress site.
I have a node application that I'd like to respond to sub.corporatewebsite.com
The node application is running Express currently. I can get it to listen to a separate port at the moment, but my service won't start if it's pointed to port 80 since it's already in use.
How can I have both apache and node listening to port 80, but having node responding to the subdomain?
You could use a reverse proxy like Nginx to route your subdomains.
Here is an example of nginx configuration, you might probaly have to complete according to your project and server :
server {
listen 80;
server_name corporatewebsite.com;
location / {
[ ... some parameters ... ]
include proxy_params; // Import global configuration for your routes
proxy_pass http://localhost:1234/; // One of your server that listens to 1234
}
}
server {
listen 80;
server_name sub.corporatewebsite.com;
location / {
[ ... some parameters ... ]
include proxy_params;
proxy_pass http://localhost:4567/; // The other server that listens to 4567
}
}
You have to configure, for example, apache2 listening to port 1234 while nodejs is listening to port 4567.
If you do like this, a good practice is to block direct access from the outside to your ports 1234 and 4567 (using iptables for example).
I think this post could be useful to you : Node.js + Nginx - What now?

setting up upstream with nginx and node?

I have three instances on aws. one for nginx which the front-end server, and two backend nodejs intstances.
Im trying to set up the nginx server to upstream to these node.js instances:
upstream node_servers {
server private_ip:8124 weight=10 max_fails=3; // node server 1 private_ip:port
server private_ip:8124 weight=10 max_fails=3; // node server 2 private_ip:port
}
server {
listen private_ip:80; // nginx server private ip:port
root /home/ubuntu/project/;
server_name public_ip.eu-west-1.compute.amazonaws.com; // nginx public DNS
location / {
try_files $uri $uri/ /index.html;
proxy_pass http://node_servers/;
}
}
on my node 1 server, node 2 server instance app.js code:
app.listen(8124, "127.0.0.1");
console.log("listening on 8124");
I go to the nginx server public domain name, and nothing really happens, its just loads forever sending request.....
In your node code, you are listening on the loopback interface on 127.0.0.1 (requests from localhost only):
app.listen(8124, "127.0.0.1");
You have to listen on your specific private IP or 0.0.0.0:
app.listen(8124, "0.0.0.0");

Resources