Host a nodejs and socketio app on a dedicated hosting (EC2) - node.js

I have a private messaging app built with nodejs and socketio which works in the url http://localhost:3000
I'm wondering how would I integrate it in a dedicated server like Amazon's EC2? I can understand that it will work on http://someip:3000 but I want the chat application to work inside a website, just like facebook. How do I set it up to work on all website pages?
Thank you

Basically you need a web server to proxy your app in the port 80 (http), this is a basic configuration for Nginx where the node app running in 127.0.0.1:3000 will be proxied to the port 80 of www.example.com that should point to the EC2 public IP:
upstream node {
ip_hash;
server 127.0.0.1:3000;
}
server {
server_name www.example.com;
access_log /var/log/nginx/www.example.com-access.log main;
error_log /var/log/nginx/www.example.com-error.log warn;
listen 80;
location / {
## Socket.io
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
## End Socket.io
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_set_header Host $http_host;
proxy_set_header Host $host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://node;
proxy_redirect off;
proxy_max_temp_file_size 0;
}
}

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;
}
}

Proxy from nginx to node - not enough worker connections

I want to setup nginx server listening on one port, proxying the connection to a different port to a nodejs application. The problem is that I get 500 error - worker_connections are not enough while connecting to upstream.
Nginx config:
upstream node {
server 127.0.0.1:1235;
keepalive 8;
}
server {
listen 1234;
server_name http://123.123.123.123:1234 node;
access_log off;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://123.123.123.123:1234/;
proxy_redirect off;
}
}
What's wrong?
You should correct your proxy_pass since you are proxying requests back to nginx itself.
According to your config it must be
proxy_pass http://node/;
You may need to add:
proxy_responses 0;
to you nginx config.

Meteor and Node virtual host

I have the need to run 2 servers, one in Node.js and one with Meteor, let's say on my_server.com
The Node server listens on my_server.com:8080,
The Meteor server listens on my_server.com:3000
I'd like to open just the port :80, and then redirect the user with vhost of Node according to the subdomain, so
node.my_server.com:80 should go to my_server.com:8080
meteor.my_server.com:80 should go to my_server.com:3000
and I want to open just one port. Is this possible?
Thank you
Yes, it's totally possible, you should use nginx of apache for that.
Here is example nginx config:
server {
listen *:80;
server_name node.my_server.com;
access_log /var/log/nginx/node.access.log;
error_log /var/log/nginx/node.error.log;
location / {
proxy_pass http://127.0.0.1: 8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header X-Forwarded-For $remote_addr;
}
}
And similar one for meteor
server {
listen *:80;
server_name meteor.my_server.com;
access_log /var/log/nginx/meteor.access.log;
error_log /var/log/nginx/meteor.error.log;
location / {
proxy_pass http://127.0.0.1: 3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header X-Forwarded-For $remote_addr;
}
}

Websocket proxy using nginx does not work with tomcat.

I am trying to proxy websocket to port 80 using nginx. We have a tomcat application running on port 8080 and the node application running on port 8888. I have been trying to proxy them to port 80 using nginx but for some reason the connection isn't being established. I am getting the following error in the console:
WebSocket connection to 'ws://chat-local-dev.guestops.com/ws/chat?access_token=bfb83713f8abecb6c3d36d3dc74c31b9&sessionId=undefined' failed: WebSocket is closed before the connection is established.
Here is my nginx configuration:
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name chat-local-dev.guestops.com;
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
server {
listen 80;
server_name api-local-dev.guestops.com;
location / {
proxy_pass http://localhost:8881;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
server {
listen 80;
server_name console-local-dev.guestops.com;
location / {
proxy_pass http://localhost:8888;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
}
I am able to run the sites on port 80 but however I am unable to run the chat between client and the server.
Any help will be highly appreciated, I can provide with the node files as well but they are big bunch of files but I can provide with the necessary files if required.
I hope I am clear enough. Thanks in advance!
nginx added websocket support in version 1.3. So you have to upgrade to version 1.3.x to use it.

Resources