Search code examples
node.jsexpressnode-http-proxy

basic node website returns "Cannot GET /" when hosted with forever.js


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

Solution

  • 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.