Node.js / Express with vhost conflict with Sails.js framework app - node.js

I am trying to setup my Nodejs/Express hosting server to have multiple applications (Sails.js app type) running on my VPS but I got this error :
/srv/data/web/vhosts/default/node_modules/vhost/index.js:78
throw new TypeError('argument server is unsupported')
^
TypeError: argument server is unsupported
at createHandle (/srv/data/web/vhosts/default/node_modules/vhost/index.js:78:9)
at vhost (/srv/data/web/vhosts/default/node_modules/vhost/index.js:39:16)
at Object.<anonymous> (/srv/data/web/vhosts/default/server.js:46:9)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:906:3
Of course I previously installed all my dependencies.
My Nodejs/Express base configuration for multiple apps is good because it works fine with this express vhosts example configuration:
https://github.com/loicsaintroch/express-vhosts
So here my nodejs server app structure:
.../vhosts/default/server.js
package.json
/app1
/app.js
/app2
/app.js
/app3
/app.js
And here my server.js file based on this previous github example:
// Module dependencies
var express = require('express');
var vhost = require('vhost');
var app = express();
// vhosts
app
.use(vhost('app1.com', require('./app1/app.js')))
.listen(8080);
And the package.json file:
{
"name": "default",
"private": true,
"version": "0.0.1",
"description": "Default git repository for some web applications.",
"dependencies": {
"express": "^4.2.0",
"vhost": "^2.0.0",
"forever": "^0.11.1",
"static-favicon": "^1.0.0",
"ejs": "^1.0.0",
"morgan": "^1.0.0",
"cookie-parser": "^1.0.1",
"body-parser": "^1.0.0",
"debug": "^0.7.4"
},
"scripts": {
"start": "forever start server.js --prod",
"debug": "node debug server.js"
},
"main": "server.js"
}
Error come from vhost npm package:
/**
* Create handle to server.
*
* #param {function|Server} server
* #return {function}
* #api private
*/
function createHandle(server){
if (typeof server === 'function') {
// callable servers are the handle
return server
} else if (typeof server.emit === 'function') {
// emit request event on server
return function handle(req, res) {
server.emit('request', req, res)
}
}
throw new TypeError('argument server is unsupported')
}
OK here precisely I think vhost package has a problem with the app.js response from sails.js framework. Here the app.js file content from my Sails.js app:
/**
* app.js
*
* Use `app.js` to run your app without `sails lift`.
* To start the server, run: `node app.js`.
*
* This is handy in situations where the sails CLI is not relevant or useful.
*
* For example:
* => `node app.js`
* => `forever start app.js`
* => `node debug app.js`
* => `modulus deploy`
* => `heroku scale`
*
*
* The same command-line arguments are supported, e.g.:
* `node app.js --silent --port=80 --prod`
*/
// Ensure a "sails" can be located:
(function() {
var sails;
try {
sails = require('sails');
} catch (e) {
console.error('To run an app using `node app.js`, you usually need to have a version of `sails` installed in the same directory as your app.');
console.error('To do that, run `npm install sails`');
console.error('');
console.error('Alternatively, if you have sails installed globally (i.e. you did `npm install -g sails`), you can use `sails lift`.');
console.error('When you run `sails lift`, your app will still use a local `./node_modules/sails` dependency if it exists,');
console.error('but if it doesn\'t, the app will run with the global sails instead!');
return;
}
// Try to get `rc` dependency
var rc;
try {
rc = require('rc');
} catch (e0) {
try {
rc = require('sails/node_modules/rc');
} catch (e1) {
console.error('Could not find dependency: `rc`.');
console.error('Your `.sailsrc` file(s) will be ignored.');
console.error('To resolve this, run:');
console.error('npm install rc --save');
rc = function () { return {}; };
}
}
// Start server
sails.lift(rc('sails'));
})();
==============================================
UPDATE: FULL SOLUTION EXAMPLE
As a synthesis of the great answer I wrote a complete case study available here
https://github.com/migswd/express-sails-vhosts
==============================================

The problem here is that you're trying to shoehorn an example meant for Express apps to work with Sails apps.
If you look at the app.js files from the example vhost apps, they all use module.exports to return an Express app instance. The app.js from the Sails app you posted clearly does no such thing; it doesn't export anything at all. Furthermore, that file is calling sails.lift, which starts its own server listening on port 1337.
A little elbow grease can get this to work. Instead of lifting the Sails app, you can use sails.load which does everything except start listening on a port. This is an asynchronous method, so it'll require a reworking of your server.js as well.
The Sails app.js files become:
var sails = require('sails');
module.exports = function(cb) {
process.chdir(__dirname);
sails.load(cb);
};
Every running sails instance exposes its underlying Express app as .hooks.http.app, so in your server.js, use async or something similar to load all of the Sails apps, then hook them up with vhost:
// Module dependencies
var express = require('express');
var vhost = require('vhost');
var app = express();
var async = require('async');
async.auto({
app1: require('./app1/app.js'),
app2: require('./app2/app.js'),
app3: require('./app3/app.js')
}, function doneLoadingApps(err, apps) {
app
.use(vhost('app1.io', apps.app1.hooks.http.app))
.use(vhost('app2.io', apps.app2.hooks.http.app))
.use(vhost('app3.io', apps.app3.hooks.http.app))
// Mix in a vanilla Express app as well
.use(vhost('app4.io', require('./app4/app.js')))
.listen(8080);
});

Related

Use newrelic in nuxt

I am trying to add newrelic agent to my nuxt application. I have installed the needed package and added my license key and set an application name in newrelic.js configuration file:
npm i newrelic
cp node_modules/newrelic/newrelic.js .
nano newrelic.js
My problem is that I also need to require this configuration file at the top of my server.js file and since this file is dynamically created and placed under the .nuxt folder I have no idea how to do this.
In a standard nodejs application I would simply add the require('newrelic'); to the top of my startup script or perhaps add a new script entry in package.json looking something like this:
"scripts": {
"dev": "node -r newrelic.js app.js"
}
I ended up using express to solve this:
npm i express
touch server/index.js
We will now load newrelic in the server/index.js file and after that create our nuxt instance:
require('newrelic');
const express = require('express');
const consola = require('consola');
const { Nuxt, Builder } = require('nuxt');
const app = express();
// Import and Set Nuxt.js options
const config = require('../nuxt.config.js');
config.dev = process.env.NODE_ENV !== 'production';
async function start () {
// Init Nuxt.js
const nuxt = new Nuxt(config);
const { host, port } = nuxt.options.server;
// Build only in dev mode
if (config.dev) {
const builder = new Builder(nuxt);
await builder.build();
} else {
await nuxt.ready();
}
// Give nuxt middleware to express
app.use(nuxt.render);
// Listen the server
app.listen(port, host);
consola.ready({
message: `Server listening on http://${host}:${port}`,
badge: true
});
}
start();
I also updated the script section in my package.json:
"scripts": {
"dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server",
"build": "nuxt build",
"start": "cross-env NODE_ENV=production node server/index.js"
}
Hope this can help anyone who faces the same kind of problem.
For anyone struggling with this I found a much simpler solution by using Nuxt modules and hooks.
Create a new file modules/newRelic.js with the following content:
module.exports = function () {
this.nuxt.hook("listen", () => {
require("newrelic");
});
};
Import the module in nuxt.config.js
modules: [
"~/modules/newRelic.js"
]
Don't forget to install newrelic (npm i newrelic) and paste newrelic.js into the applications root folder.
In Node.js, you can require a module with the -r [module] syntax (see Node.js docs) before your actual script starts up.
For Nuxt, alter your npm run scripts like this (instead nuxt start):
node -r newrelic node_modules/nuxt/bin/nuxt.js start
This way, Node loads NewRelic first, then Nuxt, and ensures NewRelic is able to instrument all dependencies. If you let Nuxt bootup first, NewRelic is not aware of some dependencies, e.g. express.
This is recommended by NewRelic, see their docs.

MongoDB Atlas error: invalid schema, expected mongodb

I am running through the Hello World app tutorial in GCP. And I am getting stuck at the server.js step.
The code of the server.js is as below:
'use strict';
const mongodb = require('mongodb');
const http = require('http');
const nconf = require('nconf');
let uri = 'mongodb+srv://my_name:<mypassword>#mydatabase-clr75.gcp.mongodb.net/test?retryWrites=true&w=majority';
if (nconf.get('mongoDatabase')) {
uri = `${uri}/${nconf.get('mongoDatabase')}`;
}
console.log(uri);
mongodb.MongoClient.connect(uri, (err, db) => {
if (err) {
throw err;
}
// Create a simple little server.
http.createServer((req, res) => {
if (req.url === '/_ah/health') {
res.writeHead(200, {
'Content-Type': 'text/plain'
});
res.write('OK');
res.end();
return;
}
const collection = db.collection('Messages');
var datetime = new Date();
const msg = {
msgDescription: '\nHello World received on ' + datetime
};
collection.insert(msg, (err) => {
if (err) {
throw err;
}
// push out a range
let msglist = '';
collection.find().toArray((err, data) => {
if (err) {
throw err;
}
data.forEach((msg) => {
msglist += `${msg.msgDescription}; `;
});
res.writeHead(200, {
'Content-Type': 'text/plain'
});
res.write('Messages received so far:\n');
res.end(msglist);
});
});
}).listen(process.env.PORT || 8080, () => {
console.log('started web process');
});
});
I receive the error as below:
mongodb+srv://my_name:#mydatabase-clr75.gcp.mongodb.net/test?retryWrites=true&w=majority
/home/herboratory/node_modules/mongodb/lib/url_parser.js:19
throw new Error('invalid schema, expected mongodb');
^ Error: invalid schema, expected mongodb
at module.exports (/home/herboratory/node_modules/mongodb/lib/url_parser.js:19:11)
at connect (/home/herboratory/node_modules/mongodb/lib/mongo_client.js:486:16)
at Function.MongoClient.connect (/home/herboratory/node_modules/mongodb/lib/mongo_client.js:250:3)
at Object. (/home/herboratory/server.js:12:21)
at Module._compile (module.js:653:30)
at Object.Module._extensions..js (module.js:664:10)
at Module.load (module.js:566:32)
at tryModuleLoad (module.js:506:12)
at Function.Module._load (module.js:498:3)
at Function.Module.runMain (module.js:694:10) npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! test#1.0.0 start: node
server.js npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the
test#1.0.0 start script. npm ERR! This is probably not a problem with
npm. There is likely additional logging output above. npm ERR! A
complete log of this run can be found in: npm ERR!
/home/herboratory/.npm/_logs/2019-06-26T03_58_26_823Z-debug.log
I was wondering it should be the format error after reading some other posts here with the same error line, so I've tried '...', "..." and without any quotation mark but still remain error. Would please guide me where's the error?
Except for the URI, is there anywhere else I also need to modify inside the code? As far as I know from the instruction I just need to insert my own Atlas Connection string.
Many thanks.
The error invalid schema, expected mongodb means that you're using an outdated node driver version. The old driver cannot parse the new mongodb+srv URI scheme.
Support for the mongodb+srv scheme was added in the node driver version 3.0 in this ticket: NODE-1145.
Upgrade your node driver using:
$ npm install mongodb
and the error should go away.
I had the same error. The problem was with setup in mongoDB Atlas and setup in my Application.
In mongoDB Atlas:
Create DATABASE and COLLECTION
Create Database User
Add your IP Address (public) in IP Whitelist, Network Access
Example of my solution:
File .env
MONGO_URI=mongodb+srv://jmendoza:your-password#cluster0-7rxkw.mongodb.net/nodeapi?retryWrites=true&w=majority
PORT=3000
File app.js
const express = require('express');
const morgan = require('morgan');
const dotenv = require('dotenv');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const expressValidator = require('express-validator');
const { postRoutes } = require('./routes/posts');
const app = express();
const port = process.env.PORT || 3000;
dotenv.config();
// BD
mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log('mongoDB, Atlas. Connected'))
.catch((err) => console.error(err));
// Middleware
app.use(morgan('dev'));
app.use(bodyParser.json());
app.use(expressValidator());
// Routes
app.use('/api/v1', postRoutes);
app.listen(port, () => {
console.log(`A NodeJS API is listining on port: ${port}`);
});
File package.json
{
"name": "node-api",
"version": "1.0.0",
"description": "A NodeJS API",
"main": "app.js",
"scripts": {
"dev": "nodemon app.js"
},
"keywords": [
"node",
"api"
],
"author": "Jonathan Mendoza",
"license": "ISC",
"dependencies": {
"body-parser": "^1.19.0",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"express-validator": "^5.3.1",
"mongoose": "^5.9.7",
"morgan": "^1.9.1",
"nodemon": "^2.0.3"
}
}
Running application (console)
jmendoza#jmendoza-ThinkPad-T420:~/IdeaProjects/NodeJS-API-Course/Basic-Node-API$ npm run dev
> node-api#1.0.0 dev /home/jmendoza/IdeaProjects/NodeJS-API-Course/Basic-Node-API
> nodemon app.js
[nodemon] 2.0.3
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node app.js`
A NodeJS API is listining on port: 3000
mongoDB, Atlas. Connected
NodeJS Version
jmendoza#jmendoza-ThinkPad-T420:~/IdeaProjects/NodeJS-API-Course/Basic-Node-API$ node -v
v13.12.0
You can see my full code on GitHub:
https://github.com/JonathanM2ndoza/NodeJS-API-Course/tree/master/Basic-Node-API

Node.js Module not found

I am experience a Module Not Found error for an NPM package that is installed and appears to be present in the node_modules folder. Is something missing in the underlying package itself?
Here is my package.json:
{
"name": "cmtest",
"version": "0.0.0",
"description": "cmtest",
"main": "server.js",
"author": {
"name": "Andrew"
},
"dependencies": {
"cloudmersive": "^1.3.2"
}
}
And then I am calling a require:
'use strict';
var http = require('http');
var Cloudmersive = require('cloudmersive');
var port = process.env.PORT || 1337;
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello World\n');
var api = new Cloudmersive.BarcodeLookupApi()
var value = "value_example"; // {String} Barcode value
var callback = function (error, data, response) {
if (error) {
console.error(error);
} else {
console.log('API called successfully. Returned data: ' + data);
}
};
api.barcodeLookupEanLookup(value, callback);
}).listen(port);
But I am getting this error:
"Cannot find module 'cloudmersive'"
"Error: Cannot find module 'cloudmersive'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:571:15)
at Function.Module._load (internal/modules/cjs/loader.js:497:25)
at Module.require (internal/modules/cjs/loader.js:626:17)
at require (internal/modules/cjs/helpers.js:20:18)
at Object.<anonymous> (c:\users\andrew\documents\visual studio 2017\Projects\cmtest\cmtest\server.js:3:20)
at Module._compile (internal/modules/cjs/loader.js:675:14)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:689:10)
at Module.load (internal/modules/cjs/loader.js:589:32)
at tryModuleLoad (internal/modules/cjs/loader.js:528:12)
at Function.Module._load (internal/modules/cjs/loader.js:520:3)"
Any ideas? Is there something wrong with the package itself? Is it a development/configuration issue on my part?
The package cloudmersive is installed with NPM and shows up in the node_modules folder. I also tried using nvm to switch between several different versions.
Underlying package source is here: https://github.com/Cloudmersive/Cloudmersive.APIClient.Javascript
Is there something wrong with the index.js file?
package.json for cloudmersive says main is src/client.invoker/index.js but the file is not in that directory.
To use the library locally without publishing to a remote npm registry, first install the dependencies by changing
into the directory containing package.json. Let’s call this JAVASCRIPT_CLIENT_DIR. Then run:
npm install
Next, link it globally in npm with the following, also from JAVASCRIPT_CLIENT_DIR:
npm link
Finally, switch to the directory you want to use your cloudmersive from, and run:
npm link /path/to/<JAVASCRIPT_CLIENT_DIR>
You should now be able to require('cloudmersive') in javascript files from the directory you ran the last
command above from.
You can checkout the README.md file inside the cloudmersive module which you have installed inside your node_modules directory to get more detailed instructions on this.

ReferenceError: describe is not defined NodeJs

I am trying to define some endpoints and do a test using nodejs. In server.js I have:
var express = require('express');
var func1 = require('./func1.js');
var port = 8080;
var server = express();
server.configure(function(){
server.use(express.bodyParser());
});
server.post('/testend/', func1.testend);
and in func1.js:
var testend = function(req, res) {
serialPort.write("1", function(err, results) {
serialPort.write("2" + "\n", function(err, results) {
});
});
});
exports.testend = testend;
Now in test.js I am trying to use this endpoint:
var should = require('should');
var assert = require('assert');
var request = require('supertest');
var http = require('http');
var app = require('./../server.js');
var port = 8080;
describe('Account', function() {
var url = "http://localhost:" + port.toString();
it('test starts', function(done) {
request(url).post('/testend/')
// end handles the response
.end(function(err, res) {
if (err) {
throw err;
}
res.body.error.should.type('string');
done();
});
});
});
But when I run node test.js I am getting this error:
describe('Account', function() {
^
ReferenceError: describe is not defined
at Object. (/test/test.js:9:1)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:906:3
How can I fix the issue?
Assuming you are testing via mocha, you have to run your tests using the mocha command instead of the node executable.
So if you haven't already, make sure you do npm install mocha -g. Then just run mocha in your project's root directory.
if you are using vscode, want to debug your files
I used tdd before, it throw ReferenceError: describe is not defined
But, when I use bdd, it works!
waste half day to solve it....
{
"type": "node",
"request": "launch",
"name": "Mocha Tests",
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
"args": [
"-u",
"bdd",// set to bdd, not tdd
"--timeout",
"999999",
"--colors",
"${workspaceFolder}/test/**/*.js"
],
"internalConsoleOptions": "openOnSessionStart"
},
To run tests with node/npm without installing Mocha globally, you can do this:
• Install Mocha locally to your project (npm install mocha --save-dev)
• Optionally install an assertion library (npm install chai --save-dev)
• In your package.json, add a section for scripts and target the mocha binary
"scripts": {
"test": "node ./node_modules/mocha/bin/mocha"
}
• Put your spec files in a directory named /test in your root directory
• In your spec files, import the assertion library
var expect = require('chai').expect;
• You don't need to import mocha, run mocha.setup, or call mocha.run()
• Then run the script from your project root:
npm test
You can also do like this:
var mocha = require('mocha')
var describe = mocha.describe
var it = mocha.it
var assert = require('chai').assert
describe('#indexOf()', function() {
it('should return -1 when not present', function() {
assert.equal([1,2,3].indexOf(4), -1)
})
})
Reference: http://mochajs.org/#require
i have this error when using "--ui tdd".
remove this or using "--ui bdd" fix problem.
OP asked about running from node not from mocha. This is a very common use case, see Using Mocha Programatically
This is what injected describe and it into my tests.
mocha.ui('bdd').run(function (failures) {
process.on('exit', function () {
process.exit(failures);
});
});
I tried tdd like in the docs, but that didn't work, bdd worked though.
for Jest you have to add "jest": true to .eslintrc
{
"env": {
"browser": true,
"es6": true,
"jest": true
},
...
Make sure you have a folder named as test that contains your test.js file.
Also make sure you have mocha available in your project by running mocha -version in terminal (at project path)
Make sure your project has package.json available, if not run npm init -y
And finally to run mocha test scripts, on terminal (on project path) run npm test

502 Bad Gateway Deploying Express Generator Template on Elastic Beanstalk

I used the express generator to create a simple express app, which when started on dev works fine on localhost:3000.
When I push this to elastic beanstalk using the eb command-- git aws.push, however, I get a 502 error on the production server.
Looking into the logs, the error I get is:
2014/04/01 19:29:40 [error] 24204#0: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.31.2.178, server: , request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8081/", host: "macenvexp-env-hqv9ucmzev.elasticbeanstalk.com"
2014/04/01 19:29:40 [error] 24204#0: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.31.2.178, server: , request: "GET /favicon.ico HTTP/1.1", upstream: "http://127.0.0.1:8081/favicon.ico", host: "macenvexp-env-hqv9ucmzev.elasticbeanstalk.com"
I'm using the default nginx configuration. When I run a node.js sample app without Express, it works fine. Here's the express code in app.js:
var express = require('express');
var http = require('http');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes');
var users = require('./routes/user');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(app.router);
app.get('/', routes.index);
app.get('/users', users.list);
/// catch 404 and forwarding to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
/// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
And here's the package.json file:
{
"name": "macEnvExp",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "DEBUG=macEnvExp node bin/www"
},
"dependencies": {
"express": "~3.4.8",
"static-favicon": "~1.0.0",
"morgan": "~1.0.0",
"cookie-parser": "~1.0.1",
"body-parser": "~1.0.0",
"debug": "~0.7.4",
"jade": "~1.3.0"
}
}
And here is bin/www:
#!/usr/bin/env node
var debug = require('debug')('my-application');
var app = require('../app');
app.configure(function(){
app.set('port', process.env.PORT || 3000);
});
console.log(app.get('port'));
var server = app.listen(app.get('port'), function() {
debug('Express server listening on port ' + server.address().port);
});
For clarity, I'll state the answer from the comments.
AWS ELB runs node app.js BEFORE npm start. node app.js doesn't give an error, but it doesn't open any ports.
The solution is to simply rename app.js to anything else except server.js (ie main.js) and reference that in bin/www by pointing to it in the /bin/www file: var app = require('../app'); to var app = require('../main');
Then it should be working correctly!
For clarity, here is what my directory looks like:
The package.json file will get called by ELB when it launches the application server. Here it has the instruction to run the start script node bin/www
This is the bin/www file that gets run. We see the require to ../main and the app.set('port'...)
Then the main.js file that runs the routing and all:
When I created the project, the main.js file was named app.js. The problem this caused was based on the priority ELB start sequences. ELB will launch the application and check first to see if app.js exists -- if it does exist, it runs node app.js, otherwise it will check if package.json exists and try to run npm start.
When the main.js had the name app.js ELB tried to start the whole application by running it. However this file doesn't open any ports.
An alternative to renaming app.js is to create an elastic beanstalk configuration file. Add a .config file into the .ebextensions folder, for example, .ebextensions/34.config. Change the NodeCommand setting in the namespace aws:elasticbeanstalk:container:nodejs to whatever command you want to run to start the server. For example, this is a minimal .config file to run npm start instead of app.js:
option_settings:
- namespace: aws:elasticbeanstalk:container:nodejs
option_name: NodeCommand
value: "npm start"
See http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_nodejs_custom_container.html and http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/command-options.html#command-options-nodejs for more information.
Edit:
An even easier way - using the AWS console, Configuration/Software has the "Node command" option - just set that to npm start.
Set running port to 8081
app.set('port', 8081);
Actually, there is another option.
At the Elastic Beanstalk console, inside your app-environment section, there is a Configuration menu item on your left side (right bellow Dashboard menu option). If you click there, you will find many configuration options. Click at Software Configuration and then define which is your node command. There explain the order of commands it tries indeed: "Command to start the Node.js application. If an empty string is specified, app.js is used, then server.js, then "npm start" in that order"
My mistake was at my start command script. It was starting nodemon:
"scripts": {
"start": "NODE_ENV=production && nodemon ./bin/www"
Then I changed to node and it worked:
"scripts": {
"start": "NODE_ENV=production && node ./bin/www"
Hope I helped someone.
If you use port 8081 for running your express app and use sudo for running node server, Your application will be accessed directly from elasticbean url without port numbers, otherwise it will display a 502 Gateway error from nginx.
Nginx proxying 8081 port by default for node app on elastibeanstalk.
Create file: .ebextensions/nodecommand.config and put the option settings below:
option_settings:
aws:elasticbeanstalk:container:nodejs:
NodeCommand: sudo pm2 start server.js (server command with sudo ie. sudo node /bin/www)
You can create another file for container commands: .ebextensions/01_init.config and put the desired commands which will be run before deployment. For example:
container_commands:
01_node_v6_install:
command: sudo curl --silent --location https://rpm.nodesource.com/setup_6.x | bash -
02_install_node:
command: sudo yum -y install nodejs
03_npm_install_gulp_webpack:
command: sudo npm install -g gulp webpack pm2
04_npm_install:
command: sudo npm install
05_webpack_run:
command: sudo webpack
In case anyone did the silly thing I did, make sure your bin folder is committed if you are using express. I had mine in my .gitignore file and this is why I was getting a 502 error.
Just remove /bin from .gitignore, commit, and the deploy changes to EB.
new to AWS and been a while since i webdeved, but was stuck tonight on same issue, and thanks to everyone in the thread, i am very happy to say that basic socket.io tutorial works now like a charm, i was just forgetting one line in package.json :
"scripts":
{
"start": "node app.js"
}
oh, and port !
the only thing i kept from elasticbean sample node.js app is this value instead of pure 3000 value :
var port = process.env.PORT || 3000;
Note: I ran into this issue and none of the solutions were working for me.
My solution was to make sure the devDependencies in package.json were actually in dependencies.
For example:
{
"name": "whaler-test",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www",
"create-db": "cd dynamodb && node createDonorsTable.js && cd ..",
"delete-db": "cd dynamodb && node deleteDonorsTable.js && cd ..",
"load-data": "cd dynamodb && node loadDonorsData.js && cd ..",
"read-data": "cd dynamodb && node readDataTest.js && cd .."
},
"dependencies": {
"cookie-parser": "~1.4.3",
"debug": "~2.6.9",
"express": "~4.16.0",
"http-errors": "~1.6.2",
"jade": "~1.11.0",
"morgan": "~1.9.0",
"nodemon": "1.17.5",
"cors": "2.8.4",
"aws-sdk": "^2.270.1"
}
}
Not:
{
"name": "whaler-test",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www",
"create-db": "cd dynamodb && node createDonorsTable.js && cd ..",
"delete-db": "cd dynamodb && node deleteDonorsTable.js && cd ..",
"load-data": "cd dynamodb && node loadDonorsData.js && cd ..",
"read-data": "cd dynamodb && node readDataTest.js && cd .."
},
"dependencies": {
"cookie-parser": "~1.4.3",
"debug": "~2.6.9",
"express": "~4.16.0",
"http-errors": "~1.6.2",
"jade": "~1.11.0",
"morgan": "~1.9.0",
"nodemon": "1.17.5"
},
devDependencies {
"cors": "2.8.4",
"aws-sdk": "^2.270.1"
}
}

Resources