将NestJS应用程序部署到弹性Beanstalk上。

6

我正在尝试将我的NestJS应用程序部署到AWS Elastic Beanstalk,但一直没有成功,有没有人可以详细说明一下如何实现?

完整解释:

我有一个nestjs应用程序和typeorm,但没有配置它与RDS一起工作,所以我们现在将其留给以后(也许有连接,我不知道)。

首先,我创建了一个CodePipeline,当我将新版本推送到我的GitHub存储库时,它会自动将整个仓库部署到在node 12.x上运行的eb实例。

现在,我希望每次git push时,实例都会安装依赖项,构建嵌套应用程序,并从/dist/main.js启动服务器。

我已经添加了一个Procfile文件:

web: npm install && npm run build && npm run start:prod

我还在EB上添加了PORT环境变量,并在main.ts上进行了配置,当找不到时使用8080。

而且我的package.json脚本和新创建的Nest应用程序一样:

  "scripts": {
    "prebuild": "rimraf dist",
    "build": "nest build",
    "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
    "start": "nest start",
    "start:dev": "nest start --watch",
    "start:debug": "nest start --debug --watch",
    "start:prod": "node dist/main",
    "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
    "test:e2e": "jest --config ./test/jest-e2e.json"
  }

在部署时,我在日志中看到它执行了类似于这样的操作:

Jan 23 20:01:14 web: > app@0.0.1 start /var/app/current
Jan 23 20:01:14 ip-172-31-17-171 web: > sudo npm i -g @nestjs/cli && node dist/main
Jan 23 20:01:14 web: We trust you have received the usual lecture from the local System
Jan 23 20:01:14 web: Administrator. It usually boils down to these three things:
Jan 23 20:01:14 web: #1) Respect the privacy of others.
Jan 23 20:01:14 web: #2) Think before you type.
Jan 23 20:01:14 web: #3) With great power comes great responsibility.
Jan 23 20:01:14 web: sudo: no tty present and no askpass program specified
Jan 23 20:01:14 web: npm ERR! code ELIFECYCLE
Jan 23 20:01:14 web: npm ERR! errno 1
Jan 23 20:01:14 web: npm ERR! app@0.0.1 start: `sudo npm i -g @nestjs/cli && node dist/main`
Jan 23 20:01:14 web: npm ERR! Exit status 1
Jan 23 20:01:14 web: npm ERR!
Jan 23 20:01:14 web: npm ERR! Failed at the app@0.0.1 start script.

当我输入环境url时,出现502错误。

可能是npm权限问题吗?或者我只需要部署/dist文件夹的某些内容?你认为问题在哪里呢?

这是我第一次尝试将后端服务器部署到eb :)


你尝试过什么?哪些地方出了问题?没有足够的信息来知道该提出什么建议。 - Jay McDoniel
我创建了一个 CodePipeline,它可以自动从我的 Github 存储库部署应用程序,然后我在根目录中添加了 Procfile 文件,并包含以下内容:"web: npm install && npm run build && npm run start:prod",以安装依赖项、构建 nest 应用程序并从新文件夹 /dist 启动应用程序。通过这些步骤,我在 EB 日志上得到了以下信息:
  1. sudo npm i -g @nestjs/cli && node dist/main
  2. NPM ERROR!此行存在状态 1:start: sudo npm i -g @nestjs/cli && node dist/main
- Sagi
更新问题并提供更多信息。不要在评论中发布,因为您受到一定数量的字符限制,并且无法换行。 - Jay McDoniel
更新了问题,谢谢! - Sagi
我根据提供的信息不知道如何修复它,但是你的问题在于sudo失败了(它试图提示输入密码并从键盘读取值 - 但脚本没有附加stdin / stdout,因此失败)。 要么避免使用sudo,要么使sudo无需密码。 免责声明:如果您以sudo用户身份运行节点,则存在安全风险。 - MisterSmith
感谢您的回答。我认为命令:sudo npm i -g @nestjs/cli && node dist/main 是由NestJS执行的,我没有找到任何可以更改它的地方。部署Nest应用程序的正常方式是什么? - Sagi
5个回答

6
  • 我之前在将 NestJS 应用程序部署到 AWS Elastic Beanstalk 上时遇到了一些困难,因此我决定在这里写下详细的部署指南。我按照步骤为您提供简单应用程序的部署指南。

  • 通常而言,部署失败的原因是因为它不知道 NEST 依赖项(未安装开发依赖项)和需要在上传到服务器之前进行编译的 TypeScript 代码。

  • 在我的情况下,使用压缩功能制作 zip 文件(可以使用命令行 eb,但首先尝试使用此方法进行简单操作)。

  • 首先,准备好 zip 文件,这对于避免部署失败非常重要。

    • 您需要制作 dist 文件夹。为此,我们首先删除 dist 文件夹并运行命令 nest build(* 此命令会为我们编译 TypeScript)。
    • 现在,我们有了 dist 文件夹,下一步我们需要将 package.json(* 此文件会安装我们需要的依赖项)复制到 dist 文件夹中,以便让服务器知道安装我们没有带来的依赖项 node_module
    • 在 package.json 中,使用 yarn start 运行 nest start,但 AWS 不知道 Nest 命令,因此我们需要通过使用 node main.js(此文件位于 dist 文件夹中,您需要正确地将路径指向 main.js)来指出它。为此,我们创建了 Procfile(参考这里)并在其中添加内容:web: node src/main.js。记得将其复制到dist 文件夹中。
    • 正确压缩文件,如此所述
  • 其次,从 AWS 控制台创建应用程序或环境,然后上传 zip 文件并获取成功状态。如果没有,请检查日志文件以了解失败原因。可能是因为没有 nest 命令 等等......

希望本指南能够帮助到您。

加油!


3
我遇到了以下EBS eb-engine.log错误:

"实例部署:您的源捆绑包中没有包括'package.json'文件。该部署未安装特定的Node.js版本。"

"实例部署未能为Node.js生成'Procfile'文件。 提供以下其中一个文件:'package.json'、'server.js'或'app.js'。 部署失败。"

使用所有先前的答案,以下内容适用于我在CodePipeline和EBS中使用:
buildspec.yml
version: 0.2
phases:
  install:
    commands:
      - npm install
  build:
    commands:
      - npm run build
  post_build:
    commands:
      - cp -R node_modules/ dist/node_modules # nodejs needs this
      - cp Procfile dist/Procfile # EBS needs this
artifacts:
  files:
    - "**/*"
  discard-paths: no
  base-directory: dist

Procfile

web: node main.js

工作原理是CodeBuild处理Nest的构建过程,而CodeDeploy只部署dist/目录下的内容

Node需要node_modules,因此在构建后,我将其复制到dist/目录下

但是EBS抱怨dist/目录下没有package.json文件或任何它可以识别的文件,由于Procfile通常位于根目录,因此将其复制到EBS找到并使用node main.js启动


1
接下来我遇到了错误:无法找到模块“/var/app/current/main.js”。 - Mickael Zana

0
"build": "nest build && cp package.json dist/",
"postbuild": "cd dist && zip ../dist.zip -r * .[^.]*",
"start": "node main.js"

只需修改这三个脚本,它对我有效。不需要 Procfile。

最后,在项目的根文件夹中,将生成的 dist.zip 文件上传到亚马逊。


0

将您的构件更改为复制所有内容,这样Codebuild就可以自动复制您的node_modules、package.json和dist文件夹。

artifacts:  
  files:  
    - "**/*"

然后在您的package.json文件中,将启动命令默认更改为production -

"start": "node dist/main"

这是我的buildspec.yml和package.json文件,在Elastic Beanstalk上的Nestjs部署中运行良好。


0

神秘的部分是: sudo npm i -g @nestjs/cli 是从哪里来的?

我也正在部署到 Elastic Beanstalk,但我的 Procfile 中只有 web: npm run start:prod。构建发生在 CI 中,我使用 GitHub Actions 完成构建。工作流文件的概述如下:

  1. 检出
  2. 设置 Node
  3. 安装依赖并构建应用程序
  4. 生成部署 ZIP 存档
  5. 上传部署存档到 Elastic Beanstalk

我建议您使您的 Procfile 像我的一样,本地运行构建脚本,使用类似 zip -r deployment.zip dist package* Procfile 的方法生成部署存档,并将其上传到 Elastic Beanstalk,看看结果如何。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接