Search code examples
node.jsexpressreverse-proxyhttp-proxynode-http-proxy

How to run node.js app on port 80 using http-proxy?


I want to run my node.js app on port 80 on Apache server. I have tried 2 methods one via Apache:

<VirtualHost *:80>
    ServerName domainName.com
    ServerAlias www.domainName.com

    ProxyRequests off

    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>

    <Location />
        ProxyPass http://domainName:8080
        ProxyPassReverse http://domainName:8080
    </Location>
</VirtualHost>

When I use this I get 502 proxy error in Chrome console. The server cannot find my CSS and Socket.io and other JS files.

UPDATE: I solved this error for CSS and normal .js files by putting http://domainName.com:8080/ in front of the links. But the problem still exist for socket.io! Socket.io cannot be found!

And the second method is using http-proxy module (this is the example I found, please see the comment below this post):

var http = require('http'),
httpProxy = require('http-proxy'),
proxyServer = httpProxy.createServer ({
    hostnameOnly: true,
    router: {
        'domain.com':       '127.0.0.1:81',
        'domain.co.uk':     '127.0.0.1:82',
        '127.0.0.1':        '127.0.0.1:83'
    }
});

proxyServer.listen(80);

Which was explained here: how to put nodejs and apache in the same port 80

I don't know how to get this one working for my code, since I'm using Express.

This is my relevant part of code:

var express = require('express');
var http = require('http');
var io = require('socket.io');
var connect = require('connect');
var sanitize = require('validator').sanitize;
var app = express();
var MemoryStore = express.session.MemoryStore;
var server = http.createServer(app);

var sessionStore = new MemoryStore();
var io = io.listen(server);
app.configure(function() {
    //app.use(express.logger());
    app.use(express.cookieParser());
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(express.session({ 
            store: sessionStore, 
            secret: 'someSecret',
            key: 'cookie.sid', maxAge: null }));
            });
app.use(app.router);
app.use("/styles", express.static(__dirname + '/styles'));
app.use("/images", express.static(__dirname + '/styles/images'));
app.use("/js", express.static(__dirname + '/js'));
// routing
app.get('/', function (req, res) {
  res.sendfile(__dirname + '/index.html');
});

server.listen(8080);

I prefer the second method, so if someone could help me get it to work I'd really appreciate it.


Solution

  • For getting socket.io to work through node http-proxy with multiple domains, here's my setup. I'm not sure if it's the best one (I would like it to work with a router object) but it works.

    var http = require('http'),
      httpProxy = require('http-proxy');
    
    httpProxy.setMaxSockets(4096);
    
    var server1 = new httpProxy.HttpProxy({
      target: {
        host: '127.0.0.1',
        port: '3000'
      }
    });
    
    var server2 = new httpProxy.HttpProxy({
      target: {
        host: '127.0.0.1',
        port: '3001'
      }
    });
    
    var server = http.createServer(function(req ,res){
      switch(req.headers.host){
        case 'server1.com':
          server1.proxyRequest(req, res);
        break;
        case 'server2.com':
          server2.proxyRequest(req, res);
        break;
      }
    });
    
    server.on('upgrade', function(req, socket, head){
      // Cases need only for servers that actually use websockets
      switch(req.headers.host){
        case 'server1.com':
          server1.proxyWebSocketRequest(req, socket, head);
        break;
        case 'server2.com':
          server2.proxyWebSocketRequest(req, socket, head);
        break;
      }
    });
    
    server.listen(80);