Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ExpressJS - Elastic Beanstalk 502 Bad Gateway

I am running a Express.js app on Amazon Elastic Beanstalk and my environment was successfully created, but when I go to my environment via the URL Amazon has created, I receive a 502 Bad Gateway nginx/1.6.2 error. While I have read other resources on StackOverflow, which suggest I rename my main file from server.js to main.js and set the port in a bin/www folder, I feel like this isn't the solution for my app. I ran node server.js, which is the command I believe Elastic Beanstalk runs and it doesn't work, (error message):

node server.js
events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: failed to connect to [undefined:27017]

because I have ENV variables set up in a .env file, so the only way I can run my server is with foreman. This has made me think that the 502 error is the result of Elastic Beanstalk not being able to comprehend the variable and thus causing the server to fail. Can anyone confirm that I am on the right path or is this issue really because my main file is named server.js and not in the bin/www folder?

Here is my code from my server.js file:

//Load express
var express = require('express');
var app = express();
var router = express.Router(); // get an instance of the router
var bodyParser = require('body-parser'); // configure app to use bodyParser()
var mongoose = require('mongoose');
var passport = require('passport');
var flash = require('connect-flash');
var morgan = require('morgan');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var aws = require('aws-sdk');

app.use(bodyParser.urlencoded({ extended: true})); // get data from a POST method
app.use(bodyParser.json());
app.use(morgan('dev'));
app.use(cookieParser());


var port = process.env.PORT || 8080; // set the port

var DB_CONFIG = process.env.DB_CONFIGURATION;
var AWS_ACCESS_KEY = process.env.AWS_ACCESS_KEY;
var AWS_SECRET_KEY = process.env.AWS_SECRET_KEY;
var S3_BUCKET = process.env.S3_BUCKET;

var blogDB = require('./config/blogDB.js');
mongoose.connect(blogDB.url);




require('./config/passport.js')(passport);


app.set('view engine', 'ejs'); // set ejs as the view engine

app.use(express.static(__dirname + '/public')); // set the public directory

app.use(session({ secret: 'thisisatest' }));
app.use(passport.initialize());
app.use(passport.session());

app.use(flash());


var routes = require('./app/routes');

app.use(routes); // use routes.js


app.listen(port);
console.log('magic is happening on port' + port);

and my package file:

{
  "name": "test",
  "main": "server.js",
  "dependencies": {
    "body-parser": "1.6.5",
    "ejs": "^1.0.0",
    "express": "^4.6.1",
    "express-paginate": "0.0.2",
    "mongoose": "~3.6.15",
    "mongoose-paginate": "^3.1.0",
    "serve-favicon": "*",
    "passport" : "~0.1.17",         
    "passport-local" : "~0.1.6",
    "connect-flash" : "~0.1.1",     
    "bcrypt-nodejs" : "latest",
    "morgan": "~1.0.0",
    "cookie-parser": "~1.0.0",
    "method-override": "~1.0.0",
    "express-session": "~1.0.0",
    "aws-sdk": "*" 
  }
}
like image 917
cphill Avatar asked Feb 25 '15 13:02

cphill


People also ask

Why Elastic Beanstalk is bad?

Elastic Beanstalk isn't great if you need a lot of environment variables. The simple reason is that Elastic Beanstalk has a hard limit of 4KB to store all key-value pairs. The environment had accumulated 74 environment variables — a few of them had exceedingly verbose names.

What port does Elastic Beanstalk use?

By default, Elastic Beanstalk configures the proxy to forward requests to your application on port 5000. You can override the default port by setting the PORT environment property to the port that your main application listens on.

How do I use Mongodb in Elastic Beanstalk?

We can then obtain the connection string for the mongo shell directly on atlas by clicking on the “Connect” button for our cluster. We select “connect via mongo shell” and copy the connection string outputted from our cluster. We enter this command on our EBS SSH session (EC2 instance) using a proper username.


2 Answers

I had the same problem tonight. It turned out that the node app had not been started even though the portal claims that it will run npm start by default.

Here is what I did to fix it:

  1. Create a directory named .ebextensions in the root of my project
  2. Inside .ebextensions create a file named nodecommand.config
  3. Inside the nodecommand.config add the following yaml:
option_settings:
  - namespace: aws:elasticbeanstalk:container:nodejs
    option_name: NodeCommand
    value: "npm start"

The full instructions are available here: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_nodejs_express.html

like image 181
GrokSrc Avatar answered Oct 16 '22 06:10

GrokSrc


  1. Add "scripts": { "start": "node app.js" } to your package.json. If your main js file is not app.js, don't forget to rename it! :)

  2. In Beanstalk console: Configuration->Software add new env var: port: 8081 (PORT: 8081) enter image description here

Important: even if you add env var as port you still have to use PORT (uppercase). That is what solved my problem. I tried to use process.env.port, but it did not work. Use process.env.PORT instead.

const port = process.env.PORT || 3000;
app.listen(port, () => {
  console.log("Server is listening on: ", port);
});
like image 13
alexfrize Avatar answered Oct 16 '22 05:10

alexfrize