0

I'm trying to get my first production node website up (just a basic hello world on my production web server).

The below is what I'm using (basic http proxy to pass off apache websites to port :9000 and node websites to port :8000). I know this part works because apache vhosts are forwarded as I expect. What does not work however is the node part -instead I get the error below

"Cannot GET /"

This is running node 0.8.1 on Ubuntu 12.04

I'm hosting this with forever.js (forever start foo.js). when I echo the NODE_ENV -it shows "production"

It might also be noted that I don't have node_modules on the path (as you will see in my require statements) **not sure if this has anything to do with my issue

var httpProxy = require('/usr/local/lib/node_modules/http-proxy/lib/node-http-proxy');
var express = require('/usr/local/lib/node_modules/express/lib/express');

httpProxy.createServer(function (req, res, proxy) {

    var nodeVhosts = ['www.mysite.com'];
    var host = req.headers['host'];
    var port = nodeVhosts.indexOf(host) > -1
        ? 8000
        : 9000;

    proxy.proxyRequest(req, res, {host: 'localhost', port: port});
}).listen(80);

var one = express.createServer();
one.get('/', function(req, res){
  res.send('Hello from app one!')
});

var app = express.createServer();
app.use(express.vhost('localhost', one));
app.listen(8000);
Toran Billups
  • 27,111
  • 40
  • 155
  • 268

2 Answers2

2

Since you are running Ubuntu, you might take a look at upstart. In case you don't know, upstart replaces the old-school-unix init-scripts approach to starting and stopping services. (Those were dark, scary days!) If you want your app to start automatically when your box boots/reboots and restart automatically after it (your app) crashes, then you want upstart. Learning the basics of upstart is easy, and then you have a tool that you can use over and over again, whether it's node, apache, nginx, postfix, mongodb, mysql, whatever!

I mean no disrespect to the good folks who work on the forever module. Arguably, it does have a solid use case, but too often it is used to imperfectly duplicate the bedrock which is already on your system -- upstart. Also, you might Google for some of the comments made by experienced users and some node.js committers about the forkability of node.js and the pitfalls, which are very relevant to forever.

I'd like to post links, but I don't have enough rep yet. Hopefully what I wrote is enough to google on.

Good luck!

Carlos
  • 1,470
  • 10
  • 18
  • interesting -I actually wrote an upstart script to run it using forever (should I just use node instead (from the upstart script that is)) ? I thought forever would be a safer runtime for the web proxy? – Toran Billups Jul 23 '12 at 23:26
  • Actually, I and many other salty old unix dogs run node apps, each one as a service managed by upstart. Fewer moving parts is usually safer. I use upstart to exec the node executable as www-data. Life is good. – Carlos Jul 24 '12 at 08:23
  • It sounds like we have similar setups. I am running nginx as my reverse proxy to (1) a node "virtual reverse proxy" handing of to four different node webapps; (2) a bugzilla instance; and (3) a landing page for lost puppies. I really enjoy how easy it is to set up vhosts with node. – Carlos Jul 24 '12 at 08:29
  • Would you mind sending me an email w/ your upstart script? Mine is currently running as root (but I need to switch this before I push the final vhost script to production clearly) – Toran Billups Jul 24 '12 at 13:33
  • Sure Toran. First thing in the morning when I get to the office. – Carlos Jul 25 '12 at 04:58
1

http-proxy module doesn't change the host header of the request, and that's what connect/express vhost uses to distinguish virtualhosts.

In this line:

proxy.proxyRequest(req, res, {host: 'localhost', port: port});

you tell the proxy server to proxy the unchanged request to localhost:port.

So what you need to do is to change:

var app = express.createServer();
app.use(express.vhost('localhost', one));
app.listen(8000);

to:

var app = express.createServer();
app.use(express.vhost('www.mysite.com', one));
app.listen(8000);

and it should work.

Alternatively you can simply set the req.headers.host to localhost before proxying.

soulcheck
  • 36,297
  • 6
  • 91
  • 90