Before I start explaining my error, let me say I'm a Windows user and don't have a lot of experience using Unix commands. So each of these steps are done using the Docker Quickstart Terminal (MINGW64).
It was a few weeks ago I first heard about docker and thought using it for a node/express website. So I installed the Docker package on my Synology server.
After finishing up the website I've done the following:
I followed the instructions on this website:
https://docs.docker.com/windows/step_one/ Up until the last step,
everything worked (including docker run hello-world)
Then it was onto "Dockerizing a Node.js web app":
https://docs.docker.com/engine/examples/nodejs_web_app/
File hierarchy:
src (C:.....\projectname)
--assets (folder)
--controllers (folder)
--public (folder)
--src (folder)
--util (folder)
--views (folder)
--node_modules (folder)
--bin (folder)
----www (file, no extention)
--app.js (file)
--Dockerfile (file, no extention)
--package.json (file)
As for content:
www:
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('projectname:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
app.js:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(require('./controllers'));
};
// catch 404 and forward 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.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
package.json:
{
"name": "projectname",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"bcrypt-nodejs": "0.0.3",
"body-parser": "~1.13.2",
"bookshelf": "^0.9.2",
"cookie-parser": "~1.3.5",
"debug": "~2.2.0",
"express": "~4.13.1",
"express-session": "^1.13.0",
"i18n": "^0.8.0",
"jade": "~1.11.0",
"knex": "^0.10.0",
"morgan": "~1.6.1",
"mysql": "^2.10.2",
"passport": "^0.3.2",
"passport-local": "^1.0.0",
"serve-favicon": "~2.3.0"
},
"devDependencies": {
"autoprefixer": "^6.3.3",
"browserify": "^13.0.0",
"connect-livereload": "^0.5.4",
"grunt": "^0.4.5",
"grunt-browserify": "^4.0.1",
"grunt-contrib-cssmin": "^0.14.0",
"grunt-contrib-sass": "^0.9.2",
"grunt-contrib-uglify": "^0.11.1",
"grunt-contrib-watch": "^0.6.1",
"grunt-postcss": "^0.7.2"
}
}
So as you can see in the package.json and www (which was generated by the express generator command), I have to write npm start to run the node/express server.
Dockerfile:
FROM centos:centos6
RUN yum install -y epel-release
RUN yum install -y nodejs npm
COPY package.json /projectname/package.json
RUN cd /projectname; npm install --production
COPY . /projectname
EXPOSE 8080
CMD ["npm", "start"]
After a successful build docker build -t username/projectname . I do get a SECURITY WARNING:
Successfully built 5ed562273b56
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.
Apart from that no errors are thrown, so I ran the image: docker run -p 49160:8080 -d username/projectname. After which I get a long hash string
de297db51ab6fb3f842abb58267c1e189d2b9de51715a619a2f5431e868dc54f
Still following the principles on https://docs.docker.com/engine/examples/nodejs_web_app/. To test the image I listed the container id using docker ps which got me this:
CONTAINER ID | IMAGE | COMMAND | CREATED | STATUS | PORTS | NAMES
So completely empty! Nothing, except for the headers of the table... But when I use the code provided in the link and build their image it does give me a result (as stated in the article):
CONTAINER ID | IMAGE | COMMAND | CREATED | STATUS | PORTS | NAMES
26d3ac309d81 | username/centos-node-testing | "node /src/index.js" | 35 minutes ago | Up 35 minutes | 0.0.0.0:49160->8080/tcp | gigantic_ritchie
Just to be sure, I tried calling the app using the curl-command: curl -i 192.168.99.100:49160. Unfortunately that gave me an error:
curl: (7) Failed to connect to 192.168.99.100 port 49160: Connection refused
The ip address is retrieved using the docker-machine ip command.
As a last resort, someone suggested to simply run the app using following command docker run username/projectname. That however gave me an error:
npm ERR! Error: ENOENT, open '/package.json'
npm ERR! If you need help, you may report this log at:
npm ERR! http://github.com/isaacs/npm/issues
npm ERR! or email it to:
npm ERR!
npm ERR! System Linux 4.1.19-boot2docker
npm ERR! command "node" "/usr/bin/npm" "start"
npm ERR! cwd /
npm ERR! node -v v0.10.42
npm ERR! npm -v 1.3.6
npm ERR! path /package.json
npm ERR! code ENOENT
npm ERR! errno 34
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /npm-debug.log
npm ERR! not ok code 0
Any ideas what might cause this?
Your container is non-existent because the command you've provided (CMD, above) is returning a non-zero exit status, and the container is destroyed due to failure. In your Dockerfile, let's please try something like the following, which should ensure that npm start is run from within your project root:
FROM centos:centos6
RUN yum install -y epel-release
RUN yum install -y nodejs npm
COPY package.json /projectname/package.json
# Set the working directory
WORKDIR /projectname
RUN npm install --production
COPY . /projectname
EXPOSE 8080
CMD ["npm", "start"]
Also, for future, you might have luck troubleshooting a container if you use docker run -it username/projectname /bin/bash.
Related
I have been searching the whole day the reason of that problem so i've decided to post it:
I can't run my server using PORT=80 npm start
I get the following message :
Port 80 requires elevated privileges
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! server#0.0.0 start: `node ./bin/www`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the server#0.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/ubuntu/.npm/_logs/2018-03-26T19_52_49_813Z-debug.log
ubuntu#ip-172-31-32-30:~/mean/server$
Here is my code :
Package.json
{
"name": "server",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www",
"prod": "PORT=80 node ./bin/www"
},
"dependencies": {
"body-parser": "~1.18.2",
"cookie-parser": "~1.4.3",
"debug": "~3.1.0",
"express": "~4.16.2",
"jade": "~1.11.0",
"mongoose": "^5.0.1",
"morgan": "~1.9.0",
"serve-favicon": "~2.4.5"
}
}
my app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var logger = require('morgan');
const mongoose = require('mongoose');
var app = express();
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname,'../public')))
mongoose.connect('mongodb://XXXXX:XXXXXX#ds12XXXX.mlab.com:2XXXX/angularXXXX', {}, (err) => {
if (err) {
console.log(err);
} else {
console.log('db connection ok!');
}
});
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, '../public/index.html'))
})
module.exports = app;
I'm using :
NPM : 5.6.0
NODE : 8.10.0
Already tried : uninstall modules and npm install again, restart AWS instance, checked if port 80 is already used
Thank you for your help
It's not your code — you can't connect to port 80 from an app started with non-root account. You could sudo the node app, but that's not a great practice.
There are a lot of ways to fix this, which you can easily find in a search, but the easiest is to just alter the iptables with something like:
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
Now you can run your node app on 8080, but reach it through port 80. If you run:
sudo iptables -t nat -L
it will show you something like:
target prot opt source destination
REDIRECT tcp -- anywhere anywhere tcp dpt:http redir ports 8080
I think this is a pretty common solution if you're just looking for a quick fix.
In my application I use :
"node": "7.2.1",
"npm": "4.4.4"
"#angular/cli": "1.4.9",
"#angular/core": "4.4.6"
I deploy my application in heroku, it build but when I run it, it show "Application error" when I check the heroku logs it shows
2018-03-05T18:09:46.391200+00:00 app[web.1]: - npm ERR! A complete log of this run can be found in:
2018-03-05T18:09:46.391279+00:00 app[web.1]: - npm ERR! /app/.npm/_logs/2018-03-05T18_09_46_383Z-debug.log
Where can I find those .log files ?
When I run "node server.js" it's still waiting without doing or showing any thing
here is my server.js file
// server.js
const express = require('express');
const app = express();
const path = require('path');
// Run the app by serving the static files
// in the dist directory
app.use(express.static(__dirname + '/dist'));
// Start the app by listening on the default
// Heroku port
app.listen(process.env.PORT || 8080);
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", '*');
res.header("Access-Control-Allow-Credentials", true);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header("Access-Control-Allow-Headers", 'Origin,X-Requested-With,Content-Type,Accept,content-type,application/json');
next();
});
app.get('/*', function (req, res) {
var origin = req.get('origin');
res.sendFile(path.join(__dirname + '/dist/index.html'));
});
How to solve this problem?
The path to your log files are outputted here:
2018-03-05T18:09:46.391279+00:00 app[web.1]: - npm ERR! /app/.npm/_logs/2018-03-05T18_09_46_383Z-debug.log
To see the entire log file run this command:
cat /app/.npm/_logs/2018-03-05T18_09_46_383Z-debug.log
Hopefully that will help you find the issue.
Also, make sure to run
ng build
before trying to serve the compiled output.
I have a valid node.js app that I want to deploy to AWS EB. It is valid because it is working on my localhost by:
npm start
The zip that I upload looks like this:
My app.js looks like:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var mysql = require('mysql');
var sequelize = require('sequelize');
var routes = require('./routes/index');
var users = require('./routes/users');
var responseDTO = require('./dto/httpResponseDTO.js');
var app = express();
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
app.use(function(err, req, res, next) {
res.status(err.status || 500);
msg = responseDTO.toReseponseDTO(false, err.name, err.errors);
res.json(msg);
});
module.exports = app;
EDIT
The package.json looks like:
{
"name" : #projectname#,
"version" : "0.1.1",
"private" : true,
"scripts" : {
"start" : "node ./bin/www"
},
"dependencies" : {
...
}
}
And the file that the script tries to run (./bin/www) looks like this:
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('mee:server');
var http = require('http');
var models = require('../models');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '8081');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
It looks like this is causing problem to EB, which says:
Impaired services on all instances.
The error log says:
Server running at http://127.0.0.1:8081/
Server running at http://127.0.0.1:8081/
npm ERR! Linux 3.14.48-33.39.amzn1.x86_64
npm ERR! argv "/opt/elasticbeanstalk/node-install/node-v0.12.6-linux-x64/bin/node" "/opt/elasticbeanstalk/node-install/node-v0.12.6-linux-x64/bin/npm" "start"
npm ERR! node v0.12.6
npm ERR! npm v2.11.2
npm ERR! path /var/app/current/package.json
npm ERR! code ENOENT
npm ERR! errno -2
npm ERR! enoent ENOENT, open '/var/app/current/package.json'
npm ERR! enoent This is most likely not a problem with npm itself
npm ERR! enoent and is related to npm not being able to find a file.
npm ERR! enoent
npm ERR! Please include the following file with any support request:
npm ERR! /var/app/current/npm-debug.log
npm ERR! Linux 3.14.48-33.39.amzn1.x86_64
npm ERR! argv "/opt/elasticbeanstalk/node-install/node-v0.12.6-linux-x64/bin/node" "/opt/elasticbeanstalk/node-install/node-v0.12.6-linux-x64/bin/npm" "start"
npm ERR! node v0.12.6
npm ERR! npm v2.11.2
npm ERR! path /var/app/current/package.json
npm ERR! code ENOENT
npm ERR! errno -2
It looks like the package.json isn't found? but from the folder structure it is there...
Please let me know what went wrong, it has been bothering me for a long time!
From the code you posted I cannot see the part when you actually start the server but from the logs I see that it starts in port 8081 which it is actually strange to me, I guess in EBS it must have a dynamic PORT
When you select the port you should use process.env.PORT || 8081 this will get the port set by EBS or use 8081 (in local for example).
Amazon has a good guide which should explain you how to deploy there a node app: http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_nodejs_express.html
Turned out for some reason, when I remote into the linux ec2 instance used by the EB, and try node --version or sudo node --version, it says command not found. I have to manually install node and npm and manually start the server. It's weird that I have to do this though..
I've checked out How to setup KoaJS in Openshift and it's still not working.
Here is a part of my package.json file:
"engines": {
"node": ">= 0.12.0",
"npm": ">= 1.0.0"
},
"dependencies": {
"co-busboy": "^1.3.0",
"forever": "^0.14.1",
"fs": "0.0.2",
"koa": "^0.18.1",
"koa-logger": "^1.2.2",
"koa-router": "^4.2.0",
"koa-static": "^1.4.9",
"path": "^0.11.14"
},
"devDependencies": {},
"bundleDependencies": [],
"private": true,
"main": "--harmony app.js"
And then to my app.js file.
This code works:
var http = require('http');
//var koa = require('koa');
//var app = koa();
var ip = process.env.OPENSHIFT_NODEJS_IP || '127.0.0.1',
port = process.env.OPENSHIFT_NODEJS_PORT || '8080';
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(port, ip);
console.log('Server running at http://'+ip+':'+port+'/');
This does not work:
var http = require('http');
var koa = require('koa');
var app = koa();
var ip = process.env.OPENSHIFT_NODEJS_IP || '127.0.0.1',
port = process.env.OPENSHIFT_NODEJS_PORT || '8080';
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(port, ip);
console.log('Server running at http://'+ip+':'+port+'/');
As you can see the only difference is that I have uncommented two lines.
Error:
Service Temporarily Unavailable
The server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later.
Apache/2.2.15 (Red Hat) Server at fela-basickarl.rhcloud.com Port 80
Error logs on OpenShift state this:
...
.../app-root/runtime/repo/node_modules/koa/lib/application.js:179
function *respond(next) {
^
SyntaxError: Unexpected token *
...
A big duh.
console.log(process.versions); reveals that I am using node 0.10.25, even though I stated in package.json that I wish to use >= 0.12.0:
{ http_parser: '2.0',
node: '0.10.25',
v8: '3.14.5.10',
ares: '1.9.1',
uv: '0.10.23',
zlib: '1.2.3',
modules: '11',
openssl: '1.0.0-fips' }
What is causing OpenShift to not use 0.12.2?
Quick deploy 0.12
https://hub.openshift.com/quickstarts/128-node-js-0-12
For people that whishes to deplot nodejs 0.12 use the link above, there's a button Deploy.
0.12.2
To deploy the specific version 0.12.2 copy the directory .openshift from https://github.com/ryanj/nodejs-custom-version-openshift and overwrite your current projects .openshift directory (I am presuming you are using OpenShifts git that was created when the app was created).
Navigate your way to your-project/.openshift/markers/ and open the file NODEJS_VERSION and add 0.12.2 at the bottom. My file looks as so:
# Uncomment one of the version lines to select the node version to use.
# The last "non-blank" version line is the one picked up by the code in
# .openshift/lib/utils
# Default: 0.10.25
#
# 0.8.24
# 0.9.1
# 0.10.25
# 0.11.11
# 0.10.25
0.12.2
Then upload your project via git to OpenShift (be in your project root directory).
git add -A .
git commit -a -m "replaced .openshift directory"
git push
--harmony flag?
as stated in ECMAScript 6 features available in Node.js 0.12 --harmony flag is still needed for certain functions.
This means adding it too your package.json file, look at my question to see an example.
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"
}
}