使用 AWS codedeploy 部署 nodejs 实例的 NPM 问题

Posted

技术标签:

【中文标题】使用 AWS codedeploy 部署 nodejs 实例的 NPM 问题【英文标题】:NPM issue deploying a nodejs instance using AWS codedeploy 【发布时间】:2016-03-06 02:30:38 【问题描述】:

我目前正在尝试通过 Github 和 AWS Codedeploy 将 nodejs 应用程序自动部署到 EC2 实例。我已尽可能严格地按照here 的说明进行操作,但我的 AfterInstall 挂钩事件遇到了障碍。

这是我的 yml 文件:

version: 0.0
os: linux
files:
  - source: /backend
    destination: /home/ec2-user/signal
permissions:
  - object: /
    pattern: "**"
    owner: ec2-user
    group: ec2-user
hooks:
  ApplicationStop:
    - location: backend/app/deploy/stop.sh
      timeout: 10
      runas: ec2-user
  BeforeInstall:
    - location: backend/app/deploy/beforeinstall.sh
      timeout: 1200
      runas: ec2-user
  AfterInstall:
    - location: backend/app/deploy/afterinstall.sh
      timeout: 1200
      runas: ec2-user
  ApplicationStart:
    - location: backend/app/deploy/start.sh
      timeout: 60
      runas: ec2-user
ValidateService:
    - location: backend/app/deploy/validate.sh
      timeout: 60
      runas: ec2-user

我通过 AWS CLI 调用部署,如下所示:

aws deploy create-deployment --application-name Signal --deployment-config-name CodeDeployDefault.OneAtATime --deployment-group-name Production --description "Deployment" --github-location repository=githubusername/repository,commitId=ABCD123 --ignore-application-stop-failures

一切正常,直到我到达 AfterInstall 阶段并执行我的“afterinstall.sh”。 该文件如下所示:

#!/bin/bash
cd /home/ec2-user/signal/app/
npm install

并产生以下错误日志,导致部署失败:

错误代码:ScriptFailed

消息: 指定位置的脚本:backend/app/deploy/afterinstall.sh 以用户身份运行 ec2-user 失败,退出代码为 127

LifecycleEvent - AfterInstall
Script - backend/app/deploy/afterinstall.sh
[stderr]/opt/codedeploy-agent/deployment-root/be9902d2-8af0-46fd-b186-23ead6bea5a4/d-SBW6YCLKC/deployment-archive/backend/app/deploy/afterinstall.sh: line 7: npm: command not found

但是,如果我 ssh 进入我的 ec2 实例,请导航到临时目录:

/opt/codedeploy-agent/deployment-root/be9902d2-8af0-46fd-b186-23ead6bea5a4/d-SBW6YCLKC/deployment-archive/backend/app/deploy/

cd /home/ec2-user/signal/app/

然后手动运行npm install,或者通过./afterinstall.sh 运行我的脚本,然后npm 运行良好。

为什么 Codedeploy 代理的情况有所不同?我正在使用runas: ec2-user,所以我会假设权限等与我作为ec2-user ssh 进入框时相同。

我做错了什么愚蠢的事情? 非常非常感谢。

【问题讨论】:

值得强调一下,因为错误信息很长。最终的错误是:npm: command not found 我猜它以ec2-user 运行,但没有运行您的登录脚本,例如.bash_profile.bashrc,所以它的路径上没有npm。 source /path_to_bash_profile 放在 afterinstall.sh 的顶部 【参考方案1】:

正如 mbaird 和 Chris 在 cmets 中准确指出的那样 - 我没有设置 PATH。所以 npm、node、pm2 和……都失败了。

通过实验,我似乎需要在 Codedeploy 部署过程的每个步骤中重新建立我的路径。所以在我的 stop.sh/beforeinstall.sh/afterinstall.sh/start.sh 的顶部,我包括:

source /home/ec2-user/.bash_profile

生活还不错。 然后我遇到了其他问题,pm2 没有在正确的工作目录中启动节点,但是对 codedeploy 脚本进行类似的调整就可以了。

事后看来,这一切都很明显,但我非常感谢您的帮助。谢谢各位!

【讨论】:

你会分享你提到的调整吗,因为看起来我正在寻找相同的东西? 这是正确答案。请务必删除 #!/bin/bash 并将其替换为源代码行。我在墙上撞了一个小时。 由于某种原因,这个命令对我不起作用。我添加了export NVM_DIR="/home/ec2-user/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh",它起作用了 @NoelBaron,谢谢伙计,你为我节省了很多未来的时间,在过去的 4 个小时里一直卡在这个问题上。【参考方案2】:

我遇到了同样的问题,因为我先安装了 nvm,然后使用 nvm install node 安装了节点。 正如@AliParr 在他的回答中提到的那样,我无法重新建立我的路径。所以我创建了一个新的 ec2 实例并没有安装 nvm。相反,我像这样安装了 node 和 npm:

sudo apt update
sudo apt install nodejs npm

现在 codedeploy 使用 npm 命令没有问题。

【讨论】:

【参考方案3】:

主机代理使用根目录相当精简的环境。退出代码 127 表示操作系统找不到加载脚本所需的文件(它可能是执行它所需的脚本)。

最好的办法是确保为 root 安装了 npm。

由于主机代理在作为服务启动时会获取 /etc/profile,因此您还可以添加使 npm 在那里工作所需的任何内容。

【讨论】:

不要以root身份运行节点。 @NoelBaron 需要详细说明吗? @beyondtdr 这是一个超级旧的线程,但本质上你应该始终将你的系统配置为以具有特定权限的已知用户身份运行节点。在大多数 AWS 服务器资源中,您将拥有类似 ec2-userubuntu 的内容。您应该以这些用户身份在这些用户可访问的端口上运行。然后使用 ELB 和网络规则将 80/443 等特权端口通过管道传输到非特权端口 (3000)。

以上是关于使用 AWS codedeploy 部署 nodejs 实例的 NPM 问题的主要内容,如果未能解决你的问题,请参考以下文章

AWS CodeDeploy蓝色/绿色部署ELB体系结构

如何在 Grafana 上显示 AWS CodeDeploy 部署

在 AWS CodeDeploy 中使用蓝/绿部署时,我们如何维护自动缩放组的状态?

如何设置AWS CodeDeploy和EC2 CodeDeploy安全环境

javascript 用于Slack消息的AWS CodeDeploy Lamda格式化程序 - node.js

完成对所有实例的部署后的 AWS CodeDeploy 挂钩?