make production future ready

This commit does the following:

Production start should use the following command `npm run
start-producion` this first runs bower install and builds the front end
app(react). Then it will use the `pm2Start` script. This script will set
up the pm2 daemons to run loopback in cluster mode. This script also use
`production-start` script instead of the regular `server` script.

The reasons are two fold: to ensure `server` is run in es7 mode, and to
wait for handshake from DB or kill itself if no DB can be found within a
certain amount of time.
This commit is contained in:
Berkeley Martinez
2015-07-24 22:22:40 -07:00
parent 00b81f408b
commit c0eda90eb1
5 changed files with 45 additions and 38 deletions

View File

@ -11,9 +11,10 @@
}, },
"scripts": { "scripts": {
"start": "babel-node server/server.js", "start": "babel-node server/server.js",
"prestart-production": "bower cache clean && bower install && gulp build",
"start-production": "node pm2Start",
"lint": "eslint --ext=.js,.jsx .", "lint": "eslint --ext=.js,.jsx .",
"test": "mocha", "test": "mocha"
"postinstall": "bower cache clean && bower install && gulp build"
}, },
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"contributors": [ "contributors": [

View File

@ -2,7 +2,7 @@ var pm2 = require('pm2');
pm2.connect(function() { pm2.connect(function() {
pm2.start({ pm2.start({
name: 'server', name: 'server',
script: 'server/server.js', script: 'server/production-start.js',
'exec_mode': 'cluster', 'exec_mode': 'cluster',
instances: '2', instances: '2',
'max_memory_restart': '900M' 'max_memory_restart': '900M'

View File

@ -1,4 +1,5 @@
// use this file with runners like node-debug
// or mocha.
require('babel/register'); require('babel/register');
var app = require('./server'); var app = require('./server');
app.start(); app.start();

View File

@ -0,0 +1,31 @@
// this ensures node understands the future
require('babel/register');
var startTime = Date.now();
var timeoutHandler;
// this is where server starts booting up
var app = require('./server');
console.log('waiting for db to connect');
var onConnect = function() {
console.log('db connected in %s ms', Date.now() - startTime);
if (timeoutHandler) {
clearTimeout(timeoutHandler);
}
app.start();
};
var timeoutHandler = setTimeout(function() {
var message =
'db did not after ' +
(Date.now() - startTime) +
' ms connect crashing hard';
console.log(message);
// purposely shutdown server
// pm2 should restart this in production
throw new Error(message);
}, 5000);
app.dataSources.db.on('connected', onConnect);

View File

@ -2,8 +2,7 @@ require('dotenv').load();
var pmx = require('pmx'); var pmx = require('pmx');
pmx.init(); pmx.init();
var R = require('ramda'), var assign = require('lodash').assign,
assign = require('lodash').assign,
loopback = require('loopback'), loopback = require('loopback'),
boot = require('loopback-boot'), boot = require('loopback-boot'),
accepts = require('accepts'), accepts = require('accepts'),
@ -199,7 +198,6 @@ app.use(
}) })
); );
var startTime = Date.now();
boot(app, { boot(app, {
appRootDir: __dirname, appRootDir: __dirname,
dev: process.env.NODE_ENV dev: process.env.NODE_ENV
@ -249,7 +247,7 @@ var passportOptions = {
} }
}; };
R.keys(passportProviders).map(function(strategy) { Object.keys(passportProviders).map(function(strategy) {
var config = passportProviders[strategy]; var config = passportProviders[strategy];
config.session = config.session !== false; config.session = config.session !== false;
passportConfigurator.configureProvider( passportConfigurator.configureProvider(
@ -310,8 +308,6 @@ if (process.env.NODE_ENV === 'development') {
}); });
} }
module.exports = app;
app.start = function() { app.start = function() {
app.listen(app.get('port'), function() { app.listen(app.get('port'), function() {
app.emit('started'); app.emit('started');
@ -323,34 +319,12 @@ app.start = function() {
}); });
}; };
module.exports = app;
// start the server if `$ node server.js` // start the server if `$ node server.js`
// in production use `$npm start-production`
// or `$node server/production` to start the server
// and wait for DB handshake
if (require.main === module) { if (require.main === module) {
if (process.env.NODE_ENV === 'production') { app.start();
var timeoutHandler;
console.log('waiting for db to connect');
var onConnect = function() {
console.log('db connected in %s ms', Date.now() - startTime);
if (timeoutHandler) {
clearTimeout(timeoutHandler);
}
app.start();
};
var timeoutHandler = setTimeout(function() {
var message =
'db did not after ' +
(Date.now() - startTime) +
' ms connect crashing hard';
console.log(message);
// purposely shutdown server
// pm2 should restart this in production
throw new Error(message);
}, 5000);
app.dataSources.db.on('connected', onConnect);
} else {
app.start();
}
} }