Node 8.9.3环境下AWS ELB部署bcrypt构建失败求助
我之前在EB环境里也踩过一模一样的坑,看你贴的CloudWatch日志,一眼就能揪出问题根源:你的环境明明配置的是Node 8.9.3,但Elastic Beanstalk实际执行npm install时,用的却是Node 6.11.5!这种Node版本不匹配,直接导致了需要编译的bcrypt依赖构建失败。
先把日志里的关键错误信息标出来:
[2018-03-21T08:55:25.254Z] INFO [2599] - [Application deployment v1.1.7@15/StartupStage0/AppDeployPreHook/50npm.sh] : Activity execution failed, because: + /opt/elasticbeanstalk/containerfiles/ebnode.py --action npm-install > bcrypt@1.0.3 install /tmp/deployment/application/node_modules/bcrypt > node-pre-gyp install --fallback-to-build Running npm install: /opt/elasticbeanstalk/node-install/node-v6.11.5-linux-x64/bin/npm
下面给你几个亲测有效的解决步骤:
1. 强制EB使用你指定的Node.js版本
EB有时候会默认用旧版本的Node,哪怕你在控制台选了新版本。解决办法是通过配置文件锁定版本:
- 在项目根目录新建
.ebextensions文件夹(如果还没有的话) - 在这个文件夹里创建
node.config文件,写入以下内容:
option_settings: - namespace: aws:elasticbeanstalk:container:nodejs option_name: NodeVersion value: 8.9.3
这个配置会明确告诉EB:就用Node 8.9.3来运行和构建我的项目。
2. 清理本地依赖后重新部署
本地先把旧的依赖和锁文件清掉,确保依赖和Node 8.9.3完全匹配:
rm -rf node_modules package-lock.json npm install
然后把更新后的package-lock.json和代码一起打包部署到EB,这样远程构建时就不会出现版本冲突了。
3. 备选方案:改用无需编译的bcryptjs
如果还是遇到编译问题,推荐换成bcryptjs——它是bcrypt的纯JavaScript实现,不需要在服务器上编译,对EB这种容器环境更友好:
- 先卸载原有的bcrypt:
npm uninstall bcrypt
- 安装bcryptjs:
npm install bcryptjs
- 最后把代码里的
require('bcrypt')改成require('bcryptjs')就行,API和原bcrypt几乎完全一致,不用改业务逻辑。
核心思路就是:编译类的依赖(比如bcrypt)对Node版本和底层环境非常敏感,必须保证构建时用的Node版本和你开发环境一致,EB的默认配置经常会踩这个版本不匹配的坑,用.ebextensions锁定版本是最稳妥的办法。
内容的提问来源于stack exchange,提问作者user1381745

