简体   繁体   English

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

[英]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. 我使用快速生成器来创建一个简单的快速应用程序,当在dev上启动时,在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. 但是,当我使用eb命令--git aws.push将其推送到弹性beanstalk时,我在生产服务器上遇到502错误。

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. 我正在使用默认的nginx配置。 When I run a node.js sample app without Express, it works fine. 当我运行没有Express的node.js示例应用程序时,它工作正常。 Here's the express code in app.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;

And here's the package.json file: 这是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"
  }
}

And here is bin/www: 这是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 . AWS ELB在npm start之前运行node app.js node app.js doesn't give an error, but it doesn't open any ports. node app.js不会出错,但它不会打开任何端口。

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'); 解决方案是简单地将app.js重命名为除server.js (即main.js )之外的任何其他内容,并通过在/ bin / www文件中指向它来引用bin / www: var app = require('../app'); to var app = require('../main'); 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. 当启动应用程序服务器时,ELB将调用package.json文件。 Here it has the instruction to run the start script node bin/www 这里有运行启动脚本node bin/www的指令 在此输入图像描述

This is the bin/www file that gets run. 这是运行的bin/www文件。 We see the require to ../main and the app.set('port'...) 我们看到要求../mainapp.set('port'...) 在此输入图像描述

Then the main.js file that runs the routing and all: 然后运行路由的main.js文件全部: 在此输入图像描述

When I created the project, the main.js file was named app.js . 当我创建的项目中, main.js文件被命名为app.js The problem this caused was based on the priority ELB start sequences. 引起的问题是基于优先级ELB启动序列。 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 . ELB将启动应用程序并首先检查app.js存在 - 如果它存在,它运行node app.js ,否则它将检查package.json存在并尝试运行npm start When the main.js had the name app.js ELB tried to start the whole application by running it. main.js的名称为app.js ELB试图通过运行它来启动整个应用程序。 However this file doesn't open any ports. 但是,此文件不会打开任何端口。

An alternative to renaming app.js is to create an elastic beanstalk configuration file. 重命名app.js的替代方法是创建弹性beanstalk配置文件。 Add a .config file into the .ebextensions folder, for example, .ebextensions/34.config . .config文件添加到.ebextensions文件夹中,例如.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. 将名称空间aws:elasticbeanstalk:container:nodejsNodeCommand设置更改为要运行以启动服务器的任何命令。 For example, this is a minimal .config file to run npm start instead of app.js : 例如,这是运行npm start而不是app.js的最小.config文件:

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. 请参阅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了解更多信息。

Edit: An even easier way - using the AWS console, Configuration/Software has the "Node command" option - just set that to npm start . 编辑:更简单的方法 - 使用AWS控制台,配置/软件具有“节点命令”选项 - 只需将其设置为npm start

将运行端口设置为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). 在Elastic Beanstalk控制台上,在app-environment部分内,左侧有一个Configuration菜单项(右下方的Dashboard菜单选项)。 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" 它解释了它尝试的命令的顺序:“启动Node.js应用程序的命令。如果指定了空字符串,则使用app.js,然后使用server.js,然后按顺序”npm start“

My mistake was at my start command script. 我的错误在于我的启动命令脚本。 It was starting nodemon: 它是启动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 502 Gateway error from nginx. 如果您使用端口8081运行您的快速应用程序并使用sudo运行节点服务器,您的应用程序将直接从elasticbean URL访问,没有端口号,否则它将显示来自nginx的502网关错误。

Nginx proxying 8081 port by default for node app on elastibeanstalk. 默认情况下,Nginx代理8081端口,用于elastibeanstalk上的节点应用程序。

Create file - . 创建文件 - 。 ebextensions /nodecommand.config and put option settings below - ebextensions /nodecommand.config并在下面输入选项设置 -

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 desired commands which will be run before deployment. ebextensions /01_init.config并放置将在部署之前运行的所需命令。 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. 如果有人做了我做过的愚蠢的事情,如果你使用快递,请确保你的'bin'文件夹已经提交。 I had mine in my '.gitignore' file and this is why I was getting a 502 error. 我的'.gitignore'文件中有我的,这就是我收到502错误的原因。

Just remove '/bin' from '.gitignore', commit, and the deploy changes to EB. 只需从'.gitignore'中删除'/ bin',提交,然后将部署更改为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 : 自从我加入AWS以来已经有一段时间了,但是我今晚也遇到了同样的问题,并且感谢线程中的每个人,我很高兴地说基本的socket.io教程现在像一个魅力,我只是忘了一个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 : 我从elasticbean示例node.js应用程序中保留的唯一内容是此值而不是纯3000值:

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. 我的解决方案是确保package.json中的devDependencies实际上是依赖项。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM