AWS Beanstalk 在部署 Nodejs 应用程序时如何使用 NPM?

Posted

技术标签:

【中文标题】AWS Beanstalk 在部署 Nodejs 应用程序时如何使用 NPM?【英文标题】:How does AWS Beanstalk use NPM when deploying a Nodejs App? 【发布时间】:2013-12-31 09:18:30 【问题描述】:

我很好奇 AWS Beanstalk 部署的整体工作流程。我假设它在某个时候运行 npm 以将软件包安装在服务器上。但我只是想知道 AWS Beanstalk 是否使用“npm install --production”的最新命令来安装软件包。目前我有一个如下所示的 packages.json 文件,并希望尽可能确保仅安装依赖项而不安装 devDependencies。

"dependencies": 
  "express": "3.4.4",
  "jade": "*",
  "restify": "~2.6.0",
  "assert": "~1.0.0",
  "orchestrate": "0.0.2",
  "chance": "~0.5.3"
, 
"devDependencies": 
  "mocha": "~1.15.1"

【问题讨论】:

【参考方案1】:

如果您设置环境变量 NPM_CONFIG_PRODUCTION=true,您可以让 AWS Elastic Beanstalk 在生产模式下运行 npm install。您可以通过 Elastic Beanstalk Web 控制台执行此操作。

或者,将以下文本保存到项目根目录中名为 .ebextensions 的目录中的任何后缀为 .config 的文件中,您可以实现相同的目的,而无需每次都在 Web 控制台中设置它们:

option_settings:

  - option_name: NPM_CONFIG_PRODUCTION
    value: true

注意:请确保您使用的是空格,而不是制表符,因为它是 YAML 格式。

我发现在 t1.micro 环境中更新新 node.js 代码的时间从大约 5 分钟减少到 90 秒,因为它没有安装所有的 devDependencies,例如 grunt、karma、mocha 等.

【讨论】:

在最新的 Elastic Beanstalk 解决方案堆栈(运行 Node.js 的 64 位 Amazon Linux 2014.03 v1.0.4)中,ebnode.py 脚本引用了默认为“true”的 NPM_USE_PRODUCTION 变量。在您的 .config 文件中将此设置为“false”将导致 npm install 在没有 --production 标志的情况下运行。我没有发现对NPM_CONFIG_PRODUCTION 变量的引用,尽管它有可能在其他地方被用来设置NPM_USE_PRODUCTION。亚马逊的任何配置文档中似乎都没有提到这两个变量。 这会运行postinstall吗? 显然不会运行postinstall,但它会运行prestart。他们是如何让 npm 的使用变得如此困难的? 您的答案几乎是完整的,尽管在 2021 年您需要使用名为 NPM_USE_PRODUCTION 而不是 NPM_CONFIG_PRODUCTION 的环境变量。【参考方案2】:

@etreworgy 的评论指出,在新版本的 Elastic Beanstalk 节点堆栈中,配置已更改。

您可以通过在 EC2 实例中运行来检查当前行为:

cat /opt/elasticbeanstalk/containerfiles/ebnode.py | grep -A 5 PRODUCTION

它从今天开始返回:

        if 'NPM_USE_PRODUCTION' not in npm_env:
            npm_env['NPM_USE_PRODUCTION'] = 'true'

        if npm_env['NPM_USE_PRODUCTION'] == 'true':
            print 'Running npm with --production flag'
            check_call([npm_path, '--production', 'install'], cwd=app_path, env=npm_env)
            check_call([npm_path, '--production', 'rebuild'], cwd=app_path, env=npm_env)
        else:
            print 'Running npm without --production flag'

因此,目前它默认使用npm install --production

对于那些想要禁用它的人(就像我去这个答案时一样),您必须在项目根文件夹的 .ebextensions 文件夹中创建一个 anything.config (其中 anything 表示任何东西;node、npm、任何你想要的),内容:

option_settings:
    - namespace: aws:elasticbeanstalk:application:environment
      option_name: NPM_USE_PRODUCTION
      value: false

【讨论】:

非常感谢,您的回答很简单,但为我解决了同样的问题。 /opt/elasticbeanstalk/containerfiles/ebnode.py 实例上没有这样的目录或文件。谁能说我在哪里可以看到这个文件? 这是我 4 年前写的,如果他们改变了我也不会感到惊讶。我不再使用 EBS,所以我无法确认,但无论如何其余答案仍然有效,默认使用 --production 标志,您可以使用 NPM_USE_PRODUCTION 禁用它,如下所示:docs.aws.amazon.com/elasticbeanstalk/latest/dg/…跨度> 【参考方案3】:

目前,Elastic Beanstalk 环境运行 npm install,没有 --production 标志。在导出开发人员提供的任何 env 自定义(即环境选项设置)之前,/opt/elasticbeanstalk/containerfiles/ebnode.py 的实例上会发生这种情况,这意味着在 EB 环境的配置中设置 NODE_ENV=production 也不会阻止处理 devDependencies。

【讨论】:

感谢您的回答。如果将其作为功能添加,那绝对是好事。我也意识到 Node.js 团队在我们所有人身上都偷偷摸摸的。 ;) 这不是一个正确的答案(至少在今天)。影响npm install 的方法是通过变量NPM_CONFIG_PRODUCTION 而不是NODE_ENV。正如我在下面自己的回答中所指出的那样,Elastic Beanstalk 确实支持这一点。 2020 年 2 月更新:“默认情况下,Elastic Beanstalk 在生产模式下安装依赖项 (npm install --production)。如果要在环境实例上安装开发依赖项,请将 NPM_USE_PRODUCTION 环境属性设置为 false 。” /opt/elasticbeanstalk/containerfiles/ebnode.py 实例上没有这样的目录或文件。谁能告诉我在哪里可以看到这个?【参考方案4】:

另一个选项是使用 npm-shrinkwrap,它的另一个好处是可以同时锁定依赖项。

AWS Elastic Beanstalk suggests it here。

【讨论】:

参考文档还指出 npm-shrinkwrap 将加快部署,因为 npm install 只需执行一次。

以上是关于AWS Beanstalk 在部署 Nodejs 应用程序时如何使用 NPM?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 node.js 应用程序部署到 AWS Elastic Beanstalk

AWS Elastic Beanstalk / NodeJS / Nginx 错误:不断收到 502 bad gateway

在 Elastic Beanstalk 和 AWS Lambda 上更新 nodejs API

如何通过部署 Node.js AWS Beanstalk 解决 /tmp/.config 中的权限问题?

是否建议将 Docker 与 AWS Elastic beanstalk 一起使用?

如何在 AWS Elastic Beanstalk 上的 Nodejs 应用程序上启用大文件的上传?