Node.JS, HAproxy and Socket.IO through NGINX, app sits in subdirectory - node.js

I've been trying for hours and have read what this site and the internet have to offer. I just can't quite seem to get Socket.IO to work properly here. I know nginx by default can't handle Socket.IO however, HAproxy can. I want nginx to serve the Node apps through unix sockets and that works great. Each have a sub directory location set by nginx, however, now I need Socket.IO for the last app and I'm at a loss of configuring at this point.
I have the latest socket.io, HAproxy 1.4.8 and nginx 1.2.1. Running ubuntu.
So reiterating, I need to get socket.io working though nginx to a node app in a subdirectory, ex: localhost/app/.
Diagram:
WEB => HAproxy => Nginx => {/app1 app1, /app2 app2, /app3 app3}
Let me now if I can offer anything else!

There is no reason to get "get socket.io working though nginx". Instead you just route HAProxy directly to Socket.IO (without Nginx in the middle).
I recommend you checkout the following links:
https://gist.github.com/1014904
http://blog.mixu.net/2011/08/13/nginx-websockets-ssl-and-socket-io-deployment/

You could use Haproxy on port 80 to front several node.js apps running on different ports.
E.g.
URL:80/app1 -> haproxy -> node app1:8080
URL:80/app2 -> haproxy -> node app2:8081
URL:80/app3 -> haproxy -> node app3:8083
UPDATE:
The following is an example HAPROXY configuration that routes requests made to http://server:80/hello to localhost:20001 and http://server:80/echo to localhost:20002
backend hello
server hellosvr 127.0.0.1:20002
backend echo
server echosvr 127.0.0.1:20001
frontend http_in
option httpclose
option forwardfor except 127.0.0.1 # stunnel already adds the header
bind *:80
acl rec_hello path_beg /hello/
use_backend hello if rec_hello
acl rec_echo path_beg /echo
use_backend echo if rec_echo

Related

Run nodejs app through HTTPS

I have a node app that is setup on SSH by running node osjs run --hostname=dc-619670cb94e6.vtxfactory.org --port=4100.
It starts at http://dc-619670cb94e6.vtxfactory.org:4100/ without problems, but instead I want to serve it through HTTPS https://dc-619670cb94e6.vtxfactory.org:4100/ , where I receive an error ERR_CONNECTION_CLOSED.
If I use the port I'm unable to reach it with https, but https://dc-619670cb94e6.vtxfactory.org/ is accessible.
How can I serve the port 4100 through htttps?
Thanks.
This is an implementation detail of OS.js. Their docs recommend setting up a reverse proxy for servers. Doing this will give you more control over SSL and ports, like you want
https://manual.os-js.org/installation/

Where do I put my Node JS app so it is accessible via the main website?

I've recently installed a nodejs app (keystone) app in my home/myusername/myappname directory.
When I visit www.mydomain.com, nothing displays - even after turning on my nodejs app.
Where should these files be?
I am running ubuntu 16.04.
In the past I have worked with a var/www folder, but I am not using apache - do I need to manually create this folder?
Thanks!
For your app to be visible it has to be running (obviously) and accessible on port 80 (if you want it to be available without adding a port number to the URL).
It doesn't matter where it is on the disk as long as it's running.
You don't need Apache or nginx or any other server. Your Node app may listen on port 80. But alternatively it can listen on some other port and your other server (Apache, nginx, etc.) can proxy the requests to that port.
But if your app is listening on, e.g. port 3000 then you should be able to access it as http://www.example.com:3000/.
Also, make sure that your domain is configured correctly. It's A record for IPv4 (or AAAA for IPv6) of the www subdomain should be equal to the publicly accessible IP address of your server.
And make sure that the port you use is not blocked by the firewall.
Update
To see how you can set the port with Keystone, see:
http://keystonejs.com/docs/configuration/#options-server
It can be either changed in the config or you can run your app with:
PORT=80 node yourApp.js
instead of:
node yourApp.js
but keep in mind that to use the port number below 1024 you will usually need the program to run as root (or add a special privilege which is more complicated).
It will also mean that this will be the only application that you can run on this server, even if you have more domain names.
If you don't want to run as root or you want to host more application, it is easiest to install nginx and proxy the requests. Such a configuration is called a "reverse proxy" - it's good to search for info and tutorials using that phrase.
The simplest nginx config would be something like this:
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://localhost:3000;
}
}
You can set it in:
/etc/nginx/sites-available/default
or in a different file as e.g.:
/etc/nginx/sites-available/example
and then symlinked as /etc/nginx/sites-enabled/example
You need to restart nginx after changing the config.
You can find more options on configuring reverse proxies here:
https://www.nginx.com/resources/admin-guide/reverse-proxy/
You need to make a proxy between Apache and your Node.js application because Node.js has a built-in server. Supose your Node.js app is served on 9000 port. Then you need to make a proxy to redirect all trafic in 80 port to 9000 port where the Node.js app is running.
1. Enable mod_proxy
You can do this through a2enmond.
sudo a2enmod proxy
sudo a2enmod proxy_http
2. Set the proxy
Edit the /etc/apache2/sites-available/example.com.conf file and add the following lines:
ProxyRequests Off
Order deny, allow from All
ProxyPass / http://0.0.0.0:9000 ProxyPassReverse / http://0.0.0.0:9000
This basically say: "Redirect all traffic from root / to http://0.0.0.0:9000. The host 0.0.0.0:9000 is where your app is running.
Finally restart apache to enable changes.

Having issues setting running Meteor app with SSL on AWS Opsworks

My base case is that my Meteor App runs perfectly on Opsworks.
I do a Meteor build, tweak the files and all is good (without HTTPS/SSL). I am not using METEORUP. I just upload my tweaked build file and deploy on opsworks.
Also, I am using the out of the box Opsworks HAPROXY loadbalancer.
I then install the SSL certificates for my app and set Meteor to list on PORT=443 as per screenshot:
In the browser, I see:
503 Service Unavailable
No server is available to handle this request.
In the log files I see:
Mar 8 03:22:51 nodejs-app1 monit[2216]: 'node_web_app_buzzy' start: /bin/bash
Mar 8 03:23:51 nodejs-app1 monit[2216]: 'node_web_app_buzzy' failed, cannot ope
n a connection to INET[127.0.0.1:443/] via TCPSSL
Any ideas welcome
Your HAproxy configuration is expecting meteor/node to respond with SSL.
It should instead, terminate SSL and talking to node/meteor in plain HTTP. This is because, meteor doesn't do SSL ; it expects a server in front to handle it.
Solution:
Update the frontend https-in section to terminate ssl and redirect to the http backend
defaults
#... add this line to enable the `X-Forwarded-For` header
option forwardfor
# ...
# .... update this section ...
frontend https-in
mode tcp
# this bit causes HAProxy to talk TLS rather than just forward the connection
bind :443 ssl crt /path/to/your/certificate
reqadd X-Forwarded-Proto:\ https
# now direct it to your plain HTTP application
acl nodejs_application_buzzy_domain_buzzy hdr_end(host) -i buzzy
use_backend nodejs_app_servers if nodejs_application_buzzy_domain_buzzy

Nginx and multiple domains

I bought some domains at godaddy.com (i.e mydomain.com) for my droplet at digitalocean.com (i.e 199.216.110.210). I run a nodejs application on port 80 on the droplet. From godaddy.com, I forward with masking mydomain.com to 199.216.110.210 and I could see may app.
Now I want to run on 199.216.110.210 several node applications on different ports, using ngnix as reverse proxy. I followed the instructions here (www.digitalocean.com/community/articles/how-to-host-multiple-node-js-applications-on-a-single-vps-with-nginx-forever-and-crontab).
My nginx .conf file is
server {
listen 80;
server_name mydomain.com;
location / {
proxy_pass http://localhost:3000;
# same as in the link above
}
}
(and I am sure it is read: when ngnix start if I put an error there, ngnix reports it).
I start the nodejs application on port 3000:
I try mydomain.com, but ngnix shows always the welcome page.
Also doing mydomain.com: 3000 does not work,
it works only with 199.216.110.210:3000.
From godaddy.com, if I forward with masking the mydomain.com to 199.216.110.210:3000 I can see may app.
But I do not like this solution. I would like domains pointing to my droplet, without specifing the port and admin them with nginx.
How can I get a domain name to use with ngnix as reverse proxy to select my apps, mapped on different domains on different ports? I suppose that forwarding from godaddy.com is somehow limited.
In your server go to /var/log/nginx and do a tail -F *log. Now in another shell restart nginx.
I suspect that your domain name is too long and nginx will complain about its hash_bucket_size is too small. If this is the case open /etc/nginx/nginx.conf and make sure that the line
server_names_hash_bucket_size 64;
exists, has a value of 64 and is uncommented. Then do sudo service nginx reload, and check if all works as expected.
I am going to detail step by step how I am able to do it in my aws ec2 instance;
I set up a DNS record to my instance, so i can set mydomain.com to 192.168.123.123 (my specific IP).
Inside my instance I have forever running my node.js app in port 3000 (I test it work by issuing curl localhost:3000 from the command line)
I then download this .sh file in order to properly intantiate nginx; curl -o nginxStarter.sh https://gist.githubusercontent.com/renatoargh/dda1fbc854f7957ec7b3/raw/c0bc1a1ec76e50cdb4336182c53a0b222edb6c0e/start.sh
I configure nginx with this configuration file. Put this file in; /etc/nginx/nginx.conf
Start nginx with this command; sudo sh nginxStarter.sh start
PS.: For multiple apps just replicate the lines that routes the requests to specific ports, very easy...! If not needed you can eliminate lines regarding out SSL.

How to run sails.js application on port 80 with example?

I have to put sails.js in port 80, but apache is already using it. How can I put both (sails.js and apache) on the same port 80? I need it because in my company all the ports are blocked except for PORT 80. (This is a realtime application with nodejs and socket.io (websockets) and in the other side a php application). Thanks a lot
You have to run Sails on any free port (1337, for example) and use Apache with mod_proxy. Make sure it's loaded in Apache config, then your virtual host will be something like this:
<VirtualHost *:80>
ServerName www.youserver.com
ProxyPass / http://localhost:1337/
ProxyPassReverse / http://localhost:1337/
</VirtualHost>
See mod_proxy documentation for more details.
Put nginx in front of sailsjs, and dump apache, or make apache run on a different port.
DigitalOcean has a great tutorial on doing this with two nodejs apps.. You can find it here.
I also wrote a blog post about it here
I do this on my server so i can run ghost blog, and sailsjs on the same server. This is how i have it setup.
NGINX Proxies blog.gorelative.com -> localhost:2368
NGINX Proxies gorelative.com -> localhost:1337
Just adapt the tutorial to proxy one domain to localhost:1337 for sailsjs, and add in the other hosts to host them normally.. or proxy the others to apache2, which probably is a waste of resources and not ideal.
AFAIK: With a bit more work your hosts don't even need to be on the same server. nginx can proxy to another server, and also do load balancing tasks.

Resources