I'm trying to build a proxy server on with Node.js on Heroku using http-proxy. Everything works fine locally, but I'm having some troubles on Heroku.
var http = require('http');var httpProxy = require('http-proxy');settings = {"localhost": process.env.LOCALHOST,"devices": process.env.DEVICES_URI}var options = { router: { } }options.router[settings.localhost + '/devices'] = settings.devices + '/devices';var port = process.env.PORT || 8000;var server = httpProxy.createServer(options).listen(port);
As you can see the in the example I set a routing object. What I say is this: when a request matches '/devices' then route the request to the the device service.(identified by the DEVICES_URI environmental var)
In development I set
- LOCALHOST = 'localhost'
- DEVICES_URI = 'http://localhost:3000'
This means that all requests going to localhost:8000/devices are proxied tolocalhost:3000/devices which is what I want. All works perfectly.
The problem is in production. It gives me a timeout error repeated multiple timesfor every request.
2012-08-23T20:18:20+00:00 heroku[router]: Error H12 (Request timeout) -> GET lelylan-api.herokuapp.com/devices dyno=web.1 queue= wait= service=30000ms status=503 bytes=0
In the production the environment vars are configured to the app names.
- LOCALHOST = 'lelylan-api.herokuapp.com'
- DEVICES_URI = 'lelylan-devices.herokuapp.com/'
I guess I'm wrong is some configurations, but after the whole day I'm still not able to figure it out.
Update
I've continued with my tests and I've seen that the proxy is not able to reach the proxied service which totally stops me.
In development I set:
- LOCALHOST = 'localhost'
- DEVICES_URI = 'lelylan-devices.herokuapp.com/'
If I call http://lelylan-devices.herokuapp.com/devices everything works fine.
If I call localhost:8000/devices (which points to http://lelylan-devices.herokuapp.com/devices) Heroku tells me there is no such an app. I guess the problem is somehow in the routing system.
Here you can access at the source code.Here the configuration vars for Heroku.
NODE_ENV => productionLOCALHOST => lelylan-api.herokuapp.comDEVICES_URI => lelylan-devices.herokuapp.comTYPES_URI => lelylan-types.herokuapp.comLOCATIONS_URI => lelylan-locations.herokuapp.com
Best Answer
I finally made it work using a slightly modified version proxy-by-url. The final code looks something like this and works fine.
var httpProxy = require('http-proxy');var port = process.env.PORT || 8000;var routing = {'/devices': { port: process.env.DEVICES_PORT || 80, host: process.env.DEVICES_URI }}var server = httpProxy.createServer(require('./lib/uri-middleware')(routing)).listen(port);
One note to remember. The plugin sets the header HOST to the destination application uri. If you do not do so, Heroku will not recognize the app and will not find it, as its internal routing system seems to be based on the HOST header.
I use http-proxy successfully on Heroku. The first thing I noticed in your log err is the url it is GETting:GET lelylan-api.herokuapp.com/tdevices
There is a typo... instead of '/devices' it shows '/tdevices'. Before continuing can you confirm this is the actual log message?