502 Bad Gateway在Elastic Beanstalk上部署Express Generator模板

时间:2014-04-01 19:39:11

标签: node.js amazon-web-services nginx express

我使用了express生成器来创建一个简单的快速应用程序,当在dev上启动时,它在localhost:3000上运行正常。

但是,当我使用eb命令--git aws.push将其推送到弹性beanstalk时,我在生产服务器上遇到502错误。

查看日志,我得到的错误是:

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"

我正在使用默认的nginx配置。当我运行没有Express的node.js示例应用程序时,它工作正常。这是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;

这是package.json文件:

{
  "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"
  }
}

这是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);
});

8 个答案:

答案 0 :(得分:86)

为清楚起见,我将在评论中说明答案。

AWS ELB在node app.js之前运行npm startnode app.js没有出错,但它不会打开任何端口。

解决方案是简单地将app.js重命名为除server.js之外的任何其他内容(即main.js),并通过在/ bin / www文件中指向它来引用bin / www中的内容: var app = require('../app');var app = require('../main');

然后它应该正常工作!


为清楚起见,这是我的目录:

ELB在启动应用程序服务器时将调用package.json文件。这里有运行启动脚本node bin/www的说明 enter image description here

这是运行的bin/www文件。我们看到../mainapp.set('port'...)的要求 enter image description here

然后运行路由的main.js文件全部: enter image description here

创建项目时,main.js文件名为app.js。引起的问题是基于优先级ELB启动序列。 ELB将启动应用程序并首先检查是否存在app.js - 如果它存在,则运行node app.js,否则它将检查package.json是否存在并尝试运行{{1} }}。 当npm start的名称为main.js时,ELB尝试通过运行它来启动整个应用程序。但是,此文件不会打开任何端口。

答案 1 :(得分:27)

重命名app.js的替代方法是创建弹性beanstalk配置文件。将.config文件添加到.ebextensions文件夹中,例如.ebextensions/34.config。将命名空间NodeCommand中的aws:elasticbeanstalk:container:nodejs设置更改为要运行以启动服务器的任何命令。例如,这是运行.config而不是npm start的最小app.js文件:

option_settings:
  - namespace: aws:elasticbeanstalk:container:nodejs
    option_name: NodeCommand
    value: "npm start"

有关详细信息,请参阅http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_nodejs_custom_container.htmlhttp://docs.aws.amazon.com/elasticbeanstalk/latest/dg/command-options.html#command-options-nodejs

编辑: 更简单的方法 - 使用AWS控制台,配置/软件具有"节点命令"选项 - 只需将其设置为npm start

答案 2 :(得分:4)

将运行端口设置为8081

app.set('port', 8081);

答案 3 :(得分:3)

实际上,还有另一种选择。

在Elastic Beanstalk控制台的app-environment部分,左侧有一个 Configuration 菜单项(右下方的Dashboard菜单选项)。如果单击那里,您会发现许多配置选项。单击软件配置,然后定义哪个是节点命令。它解释了它确实尝试的命令的顺序:"启动Node.js应用程序的命令。如果指定了一个空字符串,则使用app.js,然后使用server.js,然后" npm start"按顺序"

我的错误在于我的启动命令脚本。它是以nodemon开始的:

"scripts": {
    "start": "NODE_ENV=production && nodemon ./bin/www"

然后我改为节点并且工作正常:

"scripts": {
    "start": "NODE_ENV=production && node ./bin/www"

希望我能帮助别人。

答案 4 :(得分:3)

如果您使用端口 8081 来运行您的快速应用并使用 sudo 来运行节点服务器,您的应用程序将直接从没有端口号的elasticbean网址访问,否则它将显示502来自nginx的网关错误。

默认情况下,nginx代理8081端口,用于elastibeanstalk上的节点应用。

创建文件 - 。 ebextensions /nodecommand.config并在下面添加选项设置 -

option_settings:
  aws:elasticbeanstalk:container:nodejs:
    NodeCommand: sudo pm2 start server.js (server command with sudo ie. sudo node /bin/www)

您可以为容器命令创建另一个文件 - 。 ebextensions /01_init.config并放置将在部署之前运行的所需命令。例如 -

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

答案 5 :(得分:2)

如果有人做了我做的愚蠢的事情,请确保如果你使用快递,你的'bin'文件夹已经提交。我的'.gitignore'文件中有我的,这就是我收到502错误的原因。

从'.gitignore'中删除'/ bin',提交,并将部署更改为EB。

答案 6 :(得分:0)

注意:我遇到了这个问题,没有一个解决方案对我有用。

我的解决方案是确保package.json中的devDependencies实际上是依赖项。

例如:

{
  "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"
  }
}

不是:

{
  "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"
  }
}

答案 7 :(得分:0)

AWS的新功能,自从我进行Webdev开发以来已经有一段时间了,但是今晚在同一问题上陷入困境,并且感谢线程中的每个人,我很高兴地说基本的socket.io教程现在就像一个魅力一样工作,我当时只是忘了package.json中的一行:

"scripts":
{
"start": "node app.js"
}

哦,端口! 我从elasticbean示例node.js应用程序保留的唯一内容是此值,而不是纯3000值:

var port = process.env.PORT || 3000;