AWS CodeDeploy部署Node应用时EC2旧版Node/npm引发启动失败问询
故障根因拆解
- CodeBuild阶段安装的Node、npm、forever都存在于CodeBuild的隔离临时构建容器中,构建流程结束后容器会被销毁,所有安装的软件完全不会同步到目标EC2实例上
- CodeDeploy Agent执行生命周期钩子时,使用
ec2-user的非交互式shell环境,PATH变量只会优先指向EC2系统预置的Node v6.17.1路径,完全无法识别CodeBuild容器内的安装操作 - 日志写入EACCES报错、node_modules缺失报错,本质是
ec2-user对目标部署目录没有操作权限、脚本执行路径和实际应用代码路径不匹配,和Node版本问题是独立的两个并行故障点
分步修复方案
1. 在EC2本地完成目标Node版本的持久化安装
这一步必须直接登录EC2用ec2-user身份操作,不要在CodeBuild脚本里做相关配置:
- 先定位EC2系统预置旧版Node的路径:执行
which node,一般输出为/usr/bin/node,是系统预装版本的软链路径 - 在
ec2-user用户目录下完成nvm部署,执行nvm install 14.4.0安装目标Node版本,执行nvm alias default 14.4.0将该版本设为ec2-user的默认Node版本 - 重新登录
ec2-user的shell,验证node -v输出为v14.4.0、npm -v为对应版本,再执行npm install -g forever全局安装forever,确保安装的forever关联的是nvm路径下的Node版本,不是系统旧Node的全局目录
2. 修正CodeDeploy钩子脚本的环境加载逻辑
CodeDeploy启动钩子脚本时不会自动加载ec2-user家目录下的.bashrc、.nvm/nvm.sh等用户配置文件,会导致PATH变量缺失nvm的Node路径,自动 fallback 到系统旧Node版本。需要修改application_start.sh,在脚本最开头强制加载nvm环境:
# 强制指定ec2-user下的nvm路径 export NVM_DIR="/home/ec2-user/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # 强制切换到目标Node版本,不依赖系统默认配置 nvm use 14.4.0 # 把当前Node路径和版本打印到CodeDeploy日志,方便后续排查 echo "启动脚本当前Node路径:$(which node),版本:$(node -v)" >> /var/log/aws/codedeploy-agent/startup_debug.log
同时修复目录权限问题:
- 执行
sudo chown -R ec2-user:ec2-user /var/www/html - 执行
sudo chmod -R 755 /var/www/html - 脚本内执行
npm run server前,必须先cd到CodeDeploy同步到本地的实际应用代码目录,确保路径下存在node_modules文件夹,避免触发路径不匹配导致的node_modules缺失报错
3. 匹配appspec.yml的配置要求
- 保持
ApplicationStart钩子的执行身份为ec2-user,不需要额外提权到root - 确保钩子脚本在打包进部署artifact时,已经通过
chmod +x添加了可执行权限,否则CodeDeploy会直接拒绝执行脚本 - 不要在钩子脚本中重复安装Node环境,所有环境配置提前在EC2本地持久化完成
验证排查清单
- 重新触发Pipeline部署前,先手动在EC2上用
ec2-user身份以非交互式shell执行修改后的application_start.sh,确认可以正常加载目标Node版本、启动应用 - 部署过程中查看CodeDeploy Agent日志(默认路径
/var/log/aws/codedeploy-agent/codedeploy-agent.log),找到启动脚本的debug输出,确认当前使用的Node路径已经指向nvm目录下的v14.4.0版本,不是系统预置的旧版本 - 如果CodeBuild阶段已经完成了依赖安装,要确保artifact中包含完整的node_modules目录,否则需要在启动脚本中进入应用目录后先执行
npm install再启动服务
内容的提问来源于stack exchange,提问作者jgrewal
相关产品推荐
相关产品推荐

