避免在弹性beanstalk中重buildnode_modules

我们有一个相当简单的node.js应用程序,但是由于AWS Elastic Beanstalk部署机制,即使在单个文件提交后,也需要大约5分钟的时间才能推出新版本(通过git aws.push )。

即提交本身(和上传)是快速的(只有一个文件推送),但是然后Elastic Beanstalk从S3中取得整个包,解压缩并运行npm install ,这导致node-gyp编译一些模块。 在安装/构build完成后,Elastic Beanstalk将清除/var/app/current并将其replace为新的应用程序版本。

毋庸置疑,不需要重复build立node_modules模型,而重build需要30秒的时间才能完成,而在ec2.micro的实例上需要花费5分钟以上的时间。

我在这里看到两种方法:

  1. 调整/opt/containerfiles/ebnode.py并使用node_modules位置来避免在部署时删除和重build。
  2. 在Elastic Beanstalk EC2实例上设置一个git repo,基本上自己重写部署过程,所以/ var / app / current只在必要时才会推送并运行npm install (这使得Elastic Beanstalk看起来像OpsWorks ..)

这两个选项都缺乏宽限期,并且在Amazon更新其Elastic Beanstalk挂钩和体系结构时容易出现问题。

也许有人有一个更好的主意,如何避免不断重build的应用程序目录中已经存在的node_modules? 谢谢。

感谢Kirill,这真的很有帮助!

我只是分享我的configuration文件,只是看看npm install的简单解决scheme。 此文件需要放在项目的.ebextensions文件夹中,因为它不包含节点安装的最后一个版本,因此可以轻松使用。

它还dynamic检查已安装的节点版本,因此不需要将其包含在env.vars文件中。

.ebextensions/00_deploy_npm.config

 files: "/opt/elasticbeanstalk/env.vars" : mode: "000775" owner: root group: users content: | export NPM_CONFIG_LOGLEVEL=error export NODE_PATH=`ls -td /opt/elasticbeanstalk/node-install/node-* | head -1`/bin "/opt/elasticbeanstalk/hooks/appdeploy/pre/50npm.sh" : mode: "000775" owner: root group: users content: | #!/bin/bash . /opt/elasticbeanstalk/env.vars function error_exit { eventHelper.py --msg "$1" --severity ERROR exit $2 } #install not-installed yet app node_modules if [ ! -d "/var/node_modules" ]; then mkdir /var/node_modules ; fi if [ -d /tmp/deployment/application ]; then ln -s /var/node_modules /tmp/deployment/application/ fi OUT=$([ -d "/tmp/deployment/application" ] && cd /tmp/deployment/application && $NODE_PATH/npm install 2>&1) || error_exit "Failed to run npm install. $OUT" $? echo $OUT "/opt/elasticbeanstalk/hooks/configdeploy/pre/50npm.sh" : mode: "000666" owner: root group: users content: | #no need to run npm install during configdeploy 

25/01/13注意:更新后的脚本运行npm -g版本升级(仅在初始实例推出或重build时运行一次),并避免在EBconfiguration更改期间进行NPM操作(当应用程序目录不存在时,以避免错误加快configuration更新)。

好吧,Elastic Beanstalk与最近的node.js构build(包括大概支持的v.10.10.10)相比性能不佳,因此我决定继续并调整EB以执行以下操作:

  1. 根据您的env.config安装任何node.js版本(包括AWS EB尚不支持的最新版本)
  2. 以避免重build现有的节点模块,包括应用程序内node_modules目录
  3. 全局安装node.js(以及任何所需的模块)。

基本上,我使用env.config来replace部署和configuration钩子与自定义的(见下文)。 另外,在一个默认的EB容器设置中,一些envvariables缺失(例如$HOME ),并且node-gyp在重build期间有时会因此而失败(花了我2个小时的search时间并重新安装libxmljs来解决此问题)。

以下是随您的构build一起提供的文件。 您可以通过env.config将其注入为内联代码或通过source: URL (如本例中所示)

env.vars (所需的节点版本&arch包含在这里和env.config中,见下文)

 export HOME=/root export NPM_CONFIG_LOGLEVEL=error export NODE_VER=0.10.24 export ARCH=x86 export PATH="$PATH:/opt/elasticbeanstalk/node-install/node-v$NODE_VER-linux-$ARCH/bin/:/root/.npm" 

40install_node.sh (获取和ungzip所需的node.js版本,使全局符号链接,更新全球npm版本)

 #!/bin/bash #source env variables including node version . /opt/elasticbeanstalk/env.vars function error_exit { eventHelper.py --msg "$1" --severity ERROR exit $2 } #UNCOMMENT to update npm, otherwise will be updated on instance init or rebuild #rm -f /opt/elasticbeanstalk/node-install/npm_updated #download and extract desired node.js version OUT=$( [ ! -d "/opt/elasticbeanstalk/node-install" ] && mkdir /opt/elasticbeanstalk/node-install ; cd /opt/elasticbeanstalk/node-install/ && wget -nc http://nodejs.org/dist/v$NODE_VER/node-v$NODE_VER-linux-$ARCH.tar.gz && tar --skip-old-files -xzpf node-v$NODE_VER-linux-$ARCH.tar.gz) || error_exit "Failed to UPDATE node version. $OUT" $?. echo $OUT #make sure node binaries can be found globally if [ ! -L /usr/bin/node ]; then ln -s /opt/elasticbeanstalk/node-install/node-v$NODE_VER-linux-$ARCH/bin/node /usr/bin/node fi if [ ! -L /usr/bin/npm ]; then ln -s /opt/elasticbeanstalk/node-install/node-v$NODE_VER-linux-$ARCH/bin/npm /usr/bin/npm fi if [ ! -f "/opt/elasticbeanstalk/node-install/npm_updated" ]; then /opt/elasticbeanstalk/node-install/node-v$NODE_VER-linux-$ARCH/bin/ && /opt/elasticbeanstalk/node-install/node-v$NODE_VER-linux-$ARCH/bin/npm update npm -g touch /opt/elasticbeanstalk/node-install/npm_updated echo "YAY! Updated global NPM version to `npm -v`" else echo "Skipping NPM -g version update. To update, please uncomment 40install_node.sh:12" fi 

50npm.sh (创build/ var / node_modules,将其符号链接到应用程序目录并运行npm install。您可以从这里全局安装任何模块,它们将登陆/root/.npm)

 #!/bin/bash . /opt/elasticbeanstalk/env.vars function error_exit { eventHelper.py --msg "$1" --severity ERROR exit $2 } #install not-installed yet app node_modules if [ ! -d "/var/node_modules" ]; then mkdir /var/node_modules ; fi if [ -d /tmp/deployment/application ]; then ln -s /var/node_modules /tmp/deployment/application/ fi OUT=$([ -d "/tmp/deployment/application" ] && cd /tmp/deployment/application && /opt/elasticbeanstalk/node-install/node-v$NODE_VER-linux-$ARCH/bin/npm install 2>&1) || error_exit "Failed to run npm install. $OUT" $? echo $OUT 

env.config (这里也要注意节点的版本,为了安全起见,我们也可以在AWS控制台的env config中放入所需的节点版本,我不确定哪个设置优先。)

 packages: yum: git: [] gcc: [] make: [] openssl-devel: [] option_settings: - option_name: NODE_ENV value: production - option_name: RDS_HOSTNAME value: fill_me_in - option_name: RDS_PASSWORD value: fill_me_in - option_name: RDS_USERNAME value: fill_me_in - namespace: aws:elasticbeanstalk:container:nodejs option_name: NodeVersion value: 0.10.24 files: "/opt/elasticbeanstalk/env.vars" : mode: "000775" owner: root group: users source: https://dl.dropbox.com/.... "/opt/elasticbeanstalk/hooks/configdeploy/pre/40install_node.sh" : mode: "000775" owner: root group: users source: https://raw.github.com/.... "/opt/elasticbeanstalk/hooks/appdeploy/pre/50npm.sh" : mode: "000775" owner: root group: users source: https://raw.github.com/.... "/opt/elasticbeanstalk/hooks/configdeploy/pre/50npm.sh" : mode: "000666" owner: root group: users content: | #no need to run npm install during configdeploy "/opt/elasticbeanstalk/hooks/appdeploy/pre/40install_node.sh" : mode: "000775" owner: root group: users source: https://raw.github.com/.... 

你有它:在t1.micro实例部署现在需要20-30秒,而不是10-15分钟! 如果你每天部署10次,这个调整将在一年中为你节省3(3)个星期。 希望这有助于并特别感谢AWS EB的工作人员为我迷路的周末:)

有npm包通过截断以下文件覆盖npm install命令的默认EB行为:

  • /opt/elasticbeanstalk/hooks/appdeploy/pre/50npm.sh
  • /opt/elasticbeanstalk/hooks/configdeploy/pre/50npm.sh

https://www.npmjs.com/package/eb-disable-npm

可能比只从SO复制脚本更好,因为这个软件包被维护,并且当EB行为改变时可能会被更新。

我find了一个快速的解决scheme。 我查看了Amazon正在使用的构build脚本,如果package.json存在,他们只运行npm install 。 所以在你最初的部署之后,你可以把它改成_package.json并且npm install不会再运行了! 这不是最好的解决scheme,但如果你需要的话,这是一个快速的解决scheme!

当我部署时,我有10多分钟的构build。 解决scheme比其他人想出的要简单得多…只要将node_modules检入git! 有关推理,请参阅http://www.futurealoof.com/posts/nodemodules-in-git.html