【问题标题】:502 Bad Gateway Deploying Express Generator Template on Elastic Beanstalk502 Bad Gateway 在 Elastic Beanstalk 上部署 Express Generator 模板
【发布时间】:2014-05-12 18:52:09
【问题描述】:

我使用 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);
});

【问题讨论】:

  • 已解决。我相信这里的问题是 AWS 在 npm start 之前正在做 node app.js。 node app.js 没有给出错误,但它没有打开任何端口。所以解决方案是将 app.js 重命名为其他任何内容(我使用 main.js)并在 bin/www 中引用它。它现在工作正常。
  • 这个解决方案非常有用(我为此花了几个小时)。谢谢一堆。请详细说明您是如何发现“AWS 在 npm start 之前正在执行 node app.js”
  • 通过 AWS 教程使用 express docs.aws.amazon.com/elasticbeanstalk/latest/dg/… 我不仅需要将 app.js 重命名为其他名称,而且还必须在我的 /bin/www 文件中指向它:'var app = require ('../应用程序');'到 'var app = require('../main');'
  • 感谢这帮助了很多!当我试图解决这个问题时,我犯了另一个巨大而愚蠢的错误......我正在使用 git aws.push 推送我的更改,但没有将我的更改提交到 git/github。所以我正在推送没有更改的旧代码。 :/ 不管怎样,在你的帮助下终于把它修好了。 --您认为您可以将其作为官方答案而不仅仅是评论吗?

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


【解决方案1】:

为清楚起见,我将说明来自 cmets 的答案。

AWS ELB 在 npm start 之前运行 node app.jsnode app.js 不会报错,但不会打开任何端口。

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

那么它应该可以正常工作了!


为了清楚起见,我的目录如下所示:

package.json 文件将在 ELB 启动应用程序服务器时被调用。这里有运行启动脚本的指令node bin/www

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

然后是运行路由的main.js文件和所有:

当我创建项目时,main.js 文件被命名为app.js。这导致的问题是基于优先级 ELB 启动序列。 ELB 将启动应用程序并首先检查app.js 是否存在——如果存在,则运行node app.js,否则它将检查package.json 是否存在并尝试运行npm start。 当main.js 具有名称app.js 时,ELB 尝试通过运行它来启动整个应用程序。但是这个文件没有打开任何端口。

【讨论】:

  • 那个 /bin/www 文件在哪里?在 ex2 实例上?
  • 找到了 express 4 的结构。字面上确实在一个空白的“测试”文件夹中表达并在重命名后更新了我的 /bin/www 。仍然没有骰子:/
  • 我更新了答案以显示目录结构。我挣扎了一会儿。您正在使用 ELB(Elastic Beanstalk)对吗?我展示的目录是您上传到 ELB 的全部内容。您是通过 github 上传还是 zip 文件上传?对于 zip,您可能想尝试两件事:在我的 cas 中压缩整个文件夹 recibel,或者在 recibel 中压缩内容。
  • 将我的主文件从 app.js 更改为 main.js 解决了我所有的问题。说真的……谢谢!!!
  • 感谢您的详细解答。我想我遇到了同样的问题,并且已按照您的说明配置应用程序,但在我的情况下运行启动脚本“server/bin/www”时出现“权限被拒绝”错误。打包发行版的根文件夹包含上面的服务器目录。我还在 www 脚本上添加了 exec 权限。任何想法为什么我可能会收到此错误?
【解决方案2】:

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

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

【讨论】:

  • 我不想改变我的表达结构,所以这个答案中的最终编辑是完美的解决方法。很遗憾,AWS EB 教程中没有强调这一点。
  • AWS 控制台、配置/软件、“节点命令”设置为“npm start”对我来说非常有用!
【解决方案3】:

设置运行端口为8081

app.set('port', 8081);

【讨论】:

  • Nginx inside(对于 nodejs 应用程序)Elasticbeanstalk 监听 nodejs 服务器的 8081,默认将请求重定向到那里。如果你没有设置 PORT 环境。变量并设置 nodejs 应用服务器的端口,例如: var port = process.env.PORT | 8080; EB 会将 PORT 设置为 8081。检查:docs.aws.amazon.com/elasticbeanstalk/latest/dg/…
【解决方案4】:

其实还有一个选择。

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

我的错误在于我的启动命令脚本。它正在启动 nodemon:

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

然后我改用node,它工作了:

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

希望我能帮助到别人。

【讨论】:

    【解决方案5】:

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

    Nginx proxying 8081 port by default for node app on 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
    

    【讨论】:

      【解决方案6】:

      如果有人做了我做的傻事,如果您使用 express,请确保您的 bin 文件夹已提交。我的 .gitignore 文件中有我的,这就是我收到 502 错误的原因。

      只需从 .gitignore 中删除 /bin,提交并将更改部署到 EB。

      【讨论】:

        【解决方案7】:

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

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

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

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

        【讨论】:

          【解决方案8】:

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

          我的解决方案是确保 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"
            }
          }
          

          【讨论】:

            猜你喜欢
            • 2016-12-20
            • 1970-01-01
            • 2021-06-22
            • 2014-10-04
            • 2015-05-18
            • 2017-12-30
            • 2018-12-30
            • 2020-10-01
            • 2019-07-27
            相关资源
            最近更新 更多