我们有一个相当简单的node.js应用程序,但由于AWS Elastic Beanstalk部署机制,即使在单个文件提交后,也需要大约5分钟来推出新版本(通过git aws.push
)。 / p>
即。提交本身(和上传)很快(只推送一个文件),但随后Elastic Beanstalk从S3获取整个包,解压缩并运行npm install
,这会导致node-gyp编译一些模块。安装/构建完成后,Elastic Beanstalk会擦除/var/app/current
并将其替换为新的应用程序版本。
毋庸置疑,不需要进行常规node_modules重建,并且在我的旧Macbook Air上重建需要30秒,在ec2.micro实例上需要花费5分钟,而不是很有趣。
我在这里看到两种方法:
/opt/containerfiles/ebnode.py
并使用node_modules位置以避免在部署时删除和重建。 npm install
(这使得Elastic Beanstalk看起来像OpsWorks ..)当Amazon更新其Elastic Beanstalk挂钩和架构时,这两个选项都缺乏优势并且容易出现问题。
也许有人更清楚如何避免不断重建已存在于app dir中的node_modules?谢谢。
答案 0 :(得分:40)
谢谢基里尔,这真的很有帮助!
我只是为那些只看npm install
的简单解决方案的人分享我的配置文件。此文件需要放在项目的.ebextensions
文件夹中,因为它不包含节点安装的最新版本,并且可以使用,所以它更轻。
它还会动态检查安装的节点版本,因此不需要将其包含在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
答案 1 :(得分:38)
25/01/13注意:更新脚本以运行npm -g版本升级(仅在初始实例推出或重建时执行一次)并避免在EB配置更改期间进行NPM操作(当app目录不存在时,以避免错误并加快配置更新。)
好的,Elastic Beanstalk对最近的node.js版本(包括大概支持的v.0.10.10)表现得很狡猾,所以我决定继续调整EB以执行以下操作:
基本上,我使用env.config用自定义的替换deploy&amp; config挂钩(见下文)。此外,在默认的EB容器设置中,缺少一些env变量(例如$HOME
),而node-gyp
有时在重建期间因为它而失败(花了我2个小时的谷歌搜索并重新安装libxmljs来解决这个问题)。
以下是与您的构建一起包含的文件。您可以通过env.config注入它们作为内联代码或通过source: URL
(如本例所示)
env.vars
(此处和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
(fetch和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
(创建/ var / node_modules,将其符号链接到app dir并运行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配置中。我不确定这些设置中的哪一个优先考虑。)
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员工有所帮助并特别感谢:)
答案 2 :(得分:5)
有npm包通过截断以下文件来覆盖npm install
命令的默认EB行为:
https://www.npmjs.com/package/eb-disable-npm
可能比从SO复制脚本更好,因为这个包是维护的,并且可能会在EB行为发生变化时更新。
答案 3 :(得分:1)
我找到了一个快速解决方案。我查看了Amazon正在使用的构建脚本,如果package.json存在,它们只运行indent [0-8] ` `
type [12-16] `book`
other [17-28] `"Moby Dick"`
。因此,在初始部署后,您可以将其更改为npm install
,_package.json
将不再运行!这不是最好的解决方案,但如果您需要,它可以快速解决!
答案 4 :(得分:-6)
当我部署时,我有10多分钟的构建时间。解决方案比其他人想象的要简单得多......只需将node_modules检查成git即可!有关推理,请参阅http://www.futurealoof.com/posts/nodemodules-in-git.html