Node JS express app not serving index file on Openshift. Works on local - node.js

I've done some updates to my node app, deployed to OpenShift and now it wont send the index.html file when live. I updated Express too and fixed all the errors from there...
My Directory structure is as follows:
/Site/
....server.js
....app/
........index.html/
My server looks like this:
var express = require('express');
var app = express();
var path = require('path');
app.use(express.static('app'));
require('./server-stripe.js')(app);
app.get('*', function(req, res) {
res.sendFile(path.resolve(__dirname + 'app/index.html'));
});
var server_port = process.env.OPENSHIFT_NODEJS_PORT || 8080
var server_ip_address = process.env.OPENSHIFT_NODEJS_IP || process.env.OPENSHIFT_INTERNAL_IP ||'127.0.0.1'
app.listen(server_port, server_ip_address, function () {
console.log( "Listening on " + server_ip_address + ", server_port " + server_port )
});
It works fine on my local environment but in Production I get a 503 Service Unavailable.
Any advice would be greatly appreciated! Whits end and all that ;)
Thanks,
Matt
Edit
This is the log:
==> app-root/logs/haproxy.log <==
[WARNING] 009/181452 (443835) : Server express/local-gear is UP (leaving maintenance).
[WARNING] 009/181453 (443835) : Server express/local-gear is DOWN, reason: Layer7 wrong status, code: 404, info: "Not Found", check duration: 36ms. 0 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
[ALERT] 009/181453 (443835) : proxy 'express' has no server available!
==> app-root/logs/nodejs.log <==
Error: ENOENT, stat '/var/lib/openshift/539976e05004467473000668/app-root/runtime/repo/app/index.html'
I'm reading around the hapoxy stuff though I'm not too clued into it?

Haproxy needs your app to serve something with http 200 OK response code, from root path (http://domain.name). Otherwise it will report your gear is DOWN. You may try checking the app with curl from the app's own gear, see the deployment log for IP and port.
To serve the static files from a selected folder (here "/app") without worrying about type recognition, you can use:
app.use(express.static(__dirname + '/app'));
If the native mime types are not enough, you can extend them:
express.mime.type['ogv'] = 'video/ogg';
Otherwise, see Basic static file server in NodeJS for a 'manual' implementation of static file server.
see: http://expressjs.com/api.html

Related

Connecting to Websocket in OpenShift Online Next Gen Starter

I'm in the process of trying to get an application which I'd built on the old OpenShift Online 2 free service up and running on the new OpenShift Online 3 Starter, and I'm having a bit of trouble.
The application uses websocket, and in the old system all that was required was for the client to connect to my server on port 8443 (which was automatically routed to my server). That doesn't seem to work in the new setup however - the connection just times out - and I haven't been able to find any documentation about using websocket in the new system.
My first thought was that I needed an additional rout, but 8080 is the only port option available for routing as far as I can see.
The app lives here, and the connection is made on line 21 of this script with the line:
this.socket = new WebSocket( 'wss://' + this.server + ':' + this.port, 'tabletop-protocol' );
Which becomes, in practice:
this.socket = new WebSocket( 'wss://production-instanttabletop.7e14.starter-us-west-2.openshiftapps.com:8443/', 'tabletop-protocol' );
On the back end, the server setup is unchanged from what I had on OpenShift 2, aside from updating the IP and port lookup from env as needed, and adding logging to help diagnose the issues I've been having.
For reference, here's the node.js server code (with the logic trimmed out):
var http = require( "http" );
var ws = require( "websocket" ).server;
// Trimmed some others used by the logic...
var ip = process.env.IP || process.env.OPENSHIFT_NODEJS_IP || '0.0.0.0';
var port = process.env.PORT || process.env.OPENSHIFT_NODEJS_PORT || 8080;
/* FILE SERVER */
// Create a static file server for the client page
var pageHost = http.createServer( function( request, response ){
// Simple file server that seems to be working, if a bit slowly
// ...
} ).listen( port, ip );
/* WEBSOCKET */
// Create a websocket server for ongoing communications
var wsConnections = [];
wsServer = new ws( { httpServer: pageHost } );
// Start listening for events on the server
wsServer.on( 'request', function( request ){
// Server logic for the app, but nothing in here ever gets hit
// ...
} );
In another question it was suggested that nearly anything - including this -
could be related to the to the ongoing general issues with US West 2, but other related problems I was experiencing seem to have cleared, and that issue has been posted for a week with no update, so I figured I'd dig deeper into this on the assumption that it's something I'm doing wrong instead of them.
Anyone know more about this and what I need to do to make it work?

parse-Server cloudCode with nodejs

I am using parse-server and I want to use nodejs with cloudCode as in the example below.
This is the example:
Adding nodejs to Parse
here is the example code from the link
var http = require('http');
var express = require('express');
var bodyParser = require('body-parser');
var ParseCloud = require('parse-cloud-express');
var Parse = ParseCloud.Parse;
var app = express();
// Host static files from public/
app.use(express.static(__dirname + '/public'));
// Define a Cloud Code function:
Parse.Cloud.define('hello', function(req, res) {
res.success('Hello from Cloud Code on Node.');
});
// Mount the Cloud Code routes on the main Express app at /webhooks/
// The cloud function above will be available at /webhooks/function_hello
app.use('/webhooks', ParseCloud.app);
// Launch the HTTP server
var port = process.env.PORT || 80;
var server = http.createServer(app);
server.listen(port, function() {
console.log('Cloud Code on Node running on port ' + port + '.');
});
console.log(process.env.PORT);
I have imported all the required modules, but still, when I run the server and try to go to the link "127.0.0.1/webhooks/function_hello" I get back Cannot GET /webhooks/function_hello
Any advise?
*OUTPUT when i run the script *
undefined
Cloud Code on Node running on port 80.
UPDATE it seems that with parse's shutdown that they have changed support status for cloudcode which affects integrating it with NodeJs
Had the same issue. GET doesn't work here. You need to make a POST request, and then you'll get {"success":"Hello from Cloud Code on Node."}
Please make sure you are running the right script with node SCRIPT_NAME
It appears your express server is set to port 5000.
See: var port = process.env.PORT || 5000;
Change your URL to http://127.0.0.1:5000/webhooks/function_hello or localhost:5000/webhooks/function_hello and it should appear
If you want to run on the default port (80) you will need to run with sudo for your script and make the following change to the code.
var port = process.env.PORT || 80;
Add a folder to your directory named public. Inside that folder place a file named index.html. Type Hello World in that file, save it. Restart your server. See if you can open http://127.0.0.1/.

Socket.IO connection error

I've an application in node.js with socket.io. Everything was running completely fine, but suddenly the browser started to send this error.
failed: Error in connection
establishment:net::ERR_TUNNEL_CONNECTION_FAILED
I didn't make any code change.
The protocol used by socket is ws:// and when I try to use this url in browser
'ws://highgarden-nodejs-91180.sae1.nitrousbox.com/socket.io/?EIO=3&transport=websocket&sid=T9Unec8KbWw-GAL8AAAF'
Chrome returns this error:
Failed to load resource: net::ERR_DISALLOWED_URL_SCHEME
This is a part of the socket setup code:
server.js:
var app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server);
var port = process.env.PORT || 3000
*------------------------------------------*
// routes ===
var routes = require('./config/routes.js');
var sock = {}
routes(app, passport, sock);
io.sockets.on('connection', sock.update);
// launch ===
server.listen(port);
Thanks advance.
Hi the exception ERR_TUNNEL_CONNECTION_FAILED happens when a tunnel connection through the proxy could not be established. And the ERR_DISALLOWED_URL_SCHEME happens when the scheme of the URL is disallowed.
May you need use it behind the proxy!
Chrome 45.0.2454.101 m says the page has been disabled or moved on the server.

EC2 with socket.io

I have set up an aws micro instance for my node application. I use socket.io as well. I am getting the following error:
GET http://localhost:3000/socket.io/1/?t=1393065240268 net::ERR_CONNECTION_REFUSED
in the console at the moment when the socket connection should be created. Apart from this the node app works. I suspect that the GET should not be towards localhost but towards the address of the server.
Note that on the server side node logs that it served socket.io:
debug - served static content /socket.io.js
Here is a picture of the Security Group of my server:
.
Socket.io setup:
env = process.env.NODE_ENV || 'development',
packageJson = require('../package.json'),
http = require('http'),
express = require('express'),
RedisStore = require('connect-redis')(express),
SessionSockets = require('session.socket.io'),
path = require('path'),
settings = require('./settings'),
expose = require('express-expose')
//Configure server for io and session.socket.io
tmpApp = express(),
tmpServer = http.createServer(tmpApp),
io = require('socket.io').listen(tmpServer),
appCookieParser = express.cookieParser(settings.cookie.secret),
appRedisStore = new RedisStore(),
sessionIO = new SessionSockets(io, appRedisStore, appCookieParser)
global.App = {
app: tmpApp,
server: tmpServer,
port: process.env.PORT || 3000,
sessionIO: sessionIO,
io: io,
start: function() {
var setUp = this.util('setUp'),
socketHandler = require('./socketHandler'),
self = this
setUp.initialize(function(err, waitingGames) {
if (err) {
console.log('error at initializing the application')
process.exit(0)
}
if (!self.started) {
self.started = true
self.server.listen(self.port)
socketHandler()
console.log("Running App Version " + App.version + " on port " + App.port + " in " + App.env + " mode")
}
})
},
...
}
UPDATE
When I changed my port to 80 I get a different error:
XMLHttpRequest cannot load http://localhost/socket.io/1/?t=1393067003774. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://ec2-54-214-136-70.us-west-2.compute.amazonaws.com' is therefore not allowed access.
I found the problem. It was on the client side. I was connecting to localhost. It's a stupid error, but during development you don't pay attention to these details and it seemed natural that socket.io should connect to the root from where you serve your content.
Since I'm using EC2 and after each restart I get different DNS address I've sent to the page where I'm initializing the socket.io the correct the req.headers.host (using express-expose).

Proxy server with Node.js on Heroku

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 to
localhost:3000/devices which is what I want. All works perfectly.
The problem is in production. It gives me a timeout error repeated multiple times
for 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 => production
LOCALHOST => lelylan-api.herokuapp.com
DEVICES_URI => lelylan-devices.herokuapp.com
TYPES_URI => lelylan-types.herokuapp.com
LOCATIONS_URI => lelylan-locations.herokuapp.com
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?

Resources