在 Elastic Beanstalk 上部署 NestJS 应用程序

Posted

技术标签:

【中文标题】在 Elastic Beanstalk 上部署 NestJS 应用程序【英文标题】:Deploying NestJS application on Elastic Beanstalk 【发布时间】:2021-04-28 01:18:35 【问题描述】:

我正在尝试将我的 NestJS 应用程序部署到 AWS 弹性 beanstalk,但没有任何成功,有人可以一步一步地写下我该如何实现吗?

完整解释:

我有一个带有 typeorm 的 nestjs 应用程序,但没有将其配置为与 RDS 一起使用,所以我们暂时保留它(也许有一个连接,idk)。

首先,我创建了一个 CodePipline,当我将新版本推送到我的 github 存储库时,它会自动将整个存储库部署到我在节点 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.

所以我在输入 env url 时得到 502。

所以可能是 npm 的权限问题?或者我需要以某种方式仅部署 /dist 文件夹? 您认为问题出在哪里?

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

【问题讨论】:

你试过什么?什么不起作用?没有足够的信息知道该建议什么。 我创建了一个 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 错误!此行存在状态 1:开始:sudo npm i -g @nestjs/cli && node dist/main 请帮助 用更多信息更新问题。不要把它放在你被限制在一定数量的字符和换行符不是一件事的评论中。 更新问题,谢谢! 我不知道如何根据可用信息修复它,但您的问题是 sudo 失败(它试图提示输入密码并从键盘读取值 - 但没有标准输入/附加到脚本的标准输出因此失败)。避免使用 sudo,或者使 sudo 无密码。免责声明:如果您以 sudo 用户身份运行的节点存在安全风险。 【参考方案1】:

神秘之处在于:sudo npm i -g @nestjs/cli 来自哪里?

我也在部署到 Elastic Beanstalk,但我的 Procfile 中只有 web: npm run start:prod。构建发生在 CI 中,因为我使用的是 GitHub Actions。工作流文件的大致大纲如下:

    结帐 设置节点 安装依赖项并构建应用程序 生成部署 ZIP 存档 将部署存档上传到 Elastic Beanstalk

我建议你让你的Procfile 像我的一样,在本地运行构建脚本,使用zip -r deployment.zip dist package* Procfile 之类的东西生成部署存档,然后将其上传到 Elastic Beanstalk,看看结果如何。

【讨论】:

【参考方案2】:

更改您的工件以复制所有内容,以便 Codebuild 可以自动复制您的 node_modules、package.json、dist 文件夹。

artifacts:  
  files:  
    - "**/*"

然后在你的 package.json 中,将启动命令默认更改为生产 -

"start": "node dist/main"

这是我的 buildspec.yml 和 package.json,它们在 Elastic beanstalk 上的 Nestjs 部署中运行良好

【讨论】:

【参考方案3】:
"build": "nest build && cp package.json dist/",
"postbuild": "cd dist && zip ../dist.zip -r * .[^.]*",
"start": "node main.js"

只修改这三个脚本,它对我有用。 Procfile 不是必需的。

最后在项目的根文件夹下,我把生成的dist.zip文件上传到亚马逊

【讨论】:

【参考方案4】:

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

"实例部署:您没有在您的 源包。部署未安装特定的 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

过程文件

web: node main.js

它的工作方式是 CodeBuild 处理 Nest 构建,而 CodeDeploy 只部署 dist/ 中的内容

节点需要node_modules 所以构建后我将它复制到 dist/

但是 EBS 抱怨在 dist/ 中没有 package.json 或它识别的任何文件,并且由于 Procfile 通常位于根目录,因此复制它以便 EBS 找到它并使用 node main.js 开始

【讨论】:

在此之后我收到错误:找不到模块'/var/app/current/main.js'【参考方案5】:

我暂时无法将 nestjs 应用程序部署到 AWS 弹性豆茎,因此我决定在此处制作指南。我在这里逐步制作部署指南,用于部署简单的应用程序。

部署通常失败的原因是它不知道 NEST 依赖项(它不安装 dev 依赖项)和需要在上传到服务器之前编译的 Typescript 代码。

在我的例子中,使用压缩来制作 zip 文件(你可以使用命令行eb,但为了简单起见,请先尝试使用它)。

首先,准备 zip 文件,这对于在部署时避免 FAILED 非常重要。

您需要创建dist 文件夹。为此,我们首先删除 dist 文件夹并运行命令 nest build(* 这个为我们编译 Typescript 执行 tsc)。 现在,我们有了dist 文件夹,接下来我们需要将 package.json(* 这个为我们安装 DEPENDENCIES 的文件)复制到 dist 文件夹中,让服务器知道安装我们需要的依赖项不要把node_module 带到这里。 在package.json中,yarn start运行nest start但是AWS不知道Nest command所以我们需要使用node main.js指出它(这个文件在dist文件中,你需要使main.js 的路径正确)。为此,我们创建Procfile(参考this)并添加内容为web: node src/main.js。请记住将其复制到 dist 文件中。 正确压缩文件为this

其次,从 AWS 控制台创建应用程序或环境,然后上传 zip 文件并获得成功状态。如果没有,请检查日志文件以了解失败的原因。也许不是nest command等...

希望本指南对您有所帮助。

加油!

【讨论】:

以上是关于在 Elastic Beanstalk 上部署 NestJS 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

在 Elastic Beanstalk 上部署 Docker 环境

在 Elastic Beanstalk 上部署 Wordpress 的多个问题

在 Elastic Beanstalk 上部署 Pyramid 应用程序

在 Elastic Beanstalk 上部署 WordPress?

Elastic Beanstalk 未部署在所有实例上

在 Elastic Beanstalk 上部署 NestJS 应用程序