How to point different subdomains to different applications on the same server? (use node.js as a proxy?) - node.js

I'm setting up a node.js server but I would also like to have Apache running on there at the same time. Node is going to be the main website, and there will be subdomains that point to Apache.
The only way I can think of how to do this is have the different applications listen to different ports and then have a proxy application that listens to port 80 and then "redirects" the port according to the subdomain used. I'm not sure if this is the right way to do it, or how to do it if it is.
Research has shown me that it could be possible to use Apache as this proxy, though I would prefer it if I didn't have to. If I could somehow use node.js to do it, that would be fantastic (my preferred solution). If that is impractical/impossible, then of course I am open to other ideas.
I would really appreciate some guidance as to how to do this.

You wanted a solution that can serve both Node.js and Apache at the same time, and you wanted to have Node.js to do the reverse proxy. However, it is best to use a program that is designed for reverse proxy (Nginx, HAProxy) for that job. Using Node.js as a reverse proxy server will be inefficient.
Nginx is something I recommend. It is simple and highly efficient. You can have the Nginx server at the very front, taking in all the requests.
Here is how you setup Nginx to reverse proxy to Node
http://www.nginxtips.com/how-to-setup-nginx-as-proxy-for-nodejs/
And here is how to setup Nginx to reverse proxy to Apache
http://www.howtoforge.com/how-to-set-up-nginx-as-a-reverse-proxy-for-apache2-on-ubuntu-12.04
Simply combine the setting files of the two will enable you to serve apache and node at the same time.

Have a look through this thread
While it discusses some issues using http-proxy with WebSockets on <= 0.8.x, if you aren't doing that, you should be fine.
You can create a very basic proxy listener like so:
var http = require('http'),
httpProxy = require('http-proxy');
httpProxy.createServer(8888, 'localhost').listen(80);
And create a back-end server like so:
var http = require('http').listen(8888);
But of course, more complex implementations can be accomplished by reading the http-proxy documentation.

Related

Why use nginx if there is a proxy middleware for nodejs?

I'm really confused with reverse proxy. What i understood is in forward proxy the client know the destination server but the server doesn't know the client, in reverse proxy the server knows the client but the client doesn't know the "server" he's visiting is a actually proxying to some other server. And to use the reverse proxy you can use NGINX. But if we can use that, why do express framework middlewares like http-proxy-middleware
exist?
and if my understanding of proxy and reverse proxy is wrong please correct me
Lets take an abstract example:
You will agree that you must be using port 3000 or something to run NodeJS... Right?
And lets say you also use angular/react or html+css to run your frontend website which is lets say on port 4200 (default for angular).
Now what if you want to have only one server and want two different services (frontend in angular and backend in nodejs) to run on that single server only.
So you need something in between your client and server to distinguish between the requests whether to forward them to angular or nodejs or any other service as well that is running on the same server.
What reverse proxy such as NGINX will do is you will define some rules on the basis of which the administrator of the server can utilize same server to serve various services.
This is the simplest example I can think of on the top of my head.

NodeJS http module vs Nginx Server

I have read that proxies can be created by Nginx server for nodejs application to listen on but I am doubtful as to what exactly this will serve additional purpose and advantages compared to http module provide by nodejs for listening purpose.
For one, you can serve multiple Node applications on one server, with host based virtual servers managed by nginx, so that requests to the same port but with different Host: HTTP header reach different Node applications.
Also nginx can be set up to serve static assets without hitting your Node app and do some caching if you need it.
Those are two things that you can achieve with adding nginx to the mix but you may not need that in your case. Also, you can run a reverse proxy with Node and without nginx if that's what you prefer.

Do I have to put a reverse proxy upon NodeJS?

I've been creating web-applications using Ruby on Rails for a while, and I'm switching to NodeJS/ExpressJS for my next web-application.
I'm used to put nginx as a reverse proxy before the rack stack; but for NodeJS/ExpressJS do I have to put a reverse-proxy in front of it ? If I have to, can you explain me why ?
First of all, to put reverse proxy or not is your decision only. I can only say a cons for doing it.
Reverse proxy (especially, nginx) can be used for balancing connections. If you have several back-end servers, you can put nginx for forwarding requests between them, and if one will be down, service will work
Nginx can be used for serving static files, faster then node.js/RoR
Nginx can be used for serving SSL connection and it's make your application a little lighter
After adding reverse proxy, you can run application only on 127.0.0.1, so there can't be executed remotely without calling nginx and logging request to it.
Hope it will help you to choose for putting nginx in product enviroment.

Hosting PHP and Node.js apps on the same server with multiple domains

I have a Linode VPS, currently running lighttpd to serve up my PHP websites and listening on port 80.
I'm also running Node.js, which listens on port 81, and uses websockets and HTTP to interact with the client.
There's a couple of different domains that I would like to point to this server. Ideally, I would like the domains which host the PHP sites to all talk to the same lighttpd server, and the sites which use node.js would somehow redirect to the port node.js is listening on unbeknownst to the client (e.g. no 30x redirect).
example-php1.com:80 -> linodebox:80 lighttpd /var/www/example1
example-php2.com:80 -> linodebox:80 lighttpd /var/www/example2
example-node.com:80 -> linodebox:81 node.js
Is there a way to do this, either by setting DNS entries or tweaking iptables? Does lighttpd need to be a proxy for node.js? The websockets feature needs to work without any fallbacks, and visiting a non node domain, e.g. example-php1.com:81, should not expose the node application.
I feel the perfect solution wouldn't require changes to existing application code nor require proxying between software web servers, but I could be wrong.
What's up Tom!?
I recommend HA-Proxy, it's one of the most high performance proxies out there and should accomplish what you're trying to do there.
I'm doing something similar with nginx acting as a proxy, it's easy but not the fastest.
HA-Proxy's website is here http://haproxy.1wt.eu
If you wanted a 'pure' solution, you could probably get the answer from looking at ha-proxy's source code. You can't really do it with iptables. Something has to read the HTTP header to determine where the request came from to route it locally.
I had basically the same problem and I ended up using node-http-proxy (also available in npm as http-proxy).
You just need a simple config file:
{
router: {
'example-php1.com': 'linodebox:80',
'example-php2.com': 'linodebox:80',
'example-node.com': 'linodebox:81
}
}
Then just run node-http-proxy --config options.json and you're set. If you want to run lighttpd and node on the same machine, you'll have to start lighttpd on a different port (I use 81 for php and 3000 for node - adjusting the config is easy). I also use forever to manage my node instances.
Ya'll are gonna hate me...
I ended up going with a second IP address, then followed the Linode tutorial to setup multiple static IPs. Then, I configured lighttpd to bind to one IP address and Node.js to bind to another IP address.
This isn't a great solution as it doesn't scale.
Update: lighttpd 1.4.46 (released back in 2017) added multiple ways to accept WebSocket connections:
lighttpd mod_wstunnel
lighttpd mod_proxy
lighttpd mod_cgi

Nginx + SSL + Rails + Juggernaut (Node.js) + Engineyard

I have two different applications on the same server. One of them is running on the 80 port (mydomain.com), another on the port 443 (sub.mydomain.com) and has wildcard certificate.
The first application is only for information purposes and don't need websockets support.
The second application should have secure websockets support (wss protocol).
I tried to set up juggernaut gem (for websockets) for my rails app with nginx server on the engineyard cloud, but i have one problem. Engineyard cloud provide only two opened ports: 80 and 443. I know that nginx do not fully support http 1.1 reverse proxing, so i can't use proxing from nginx for redirects websockets requests to the specific local port (in my case this port is 8080).
I tried use HAProxy and it's work for me when i use only unsecure websockets, but i need to support secure websockets. As i know in this case i should use something like STunnel for tunneling my https request and than use HAProxy, but when i test it - i saw that the server has to work several times slower and i still did not work to use the secure socket connection :(
Maybe I'm doing something wrong? Maybe someone will tell how to set up nginx for multiple applications (one of them should work via https) and secure websockets using only two ports (80 and 443).
p.s. Also i used a node-http-proxy, in this case i was able to set up proxy for different nginx applications but i do not get run websockets (happened only for "handshake" via nginx, not for "switching protocols")
I did some research on the various reverse proxies and websockets not too long ago. The bottom line is that websockets is new, and the reverse proxy support for it is very poor right now.
The recommendation I saw and I agree with is that you should run your websockets on a different stack than the rest of your items. That usually means putting it on a separate domain or subdomain.
You still have to deal with the complexities of getting the reverse proxies working, but it will be less complicated if you don't have to worry about breaking the other stuff.
Also, I agree that maybe you'll get better answers at serverfault or superuser.

Resources