如何持续部署Nest.js应用程序到Heroku

328 阅读8分钟

如果你已经在软件开发领域工作了一段时间,特别是网络开发,那么你知道在历史上,将你的源代码部署到网络服务器上是多么的繁琐和紧张。大多数时候,这是通过使用文件传输协议(FTP)进行上传来完成的。但现在我们有许多方法可以使部署过程自动化。在本教程中,我们将学习如何使用CircleCI设置Nest.js应用程序的持续部署到Heroku。

前提条件

以下是你从本教程中获得最佳效果的必要条件和关键条件。

  • 在您的计算机上安装Node.js
  • 在你的电脑上安装Nest CLI
  • 一个GitHub账户
  • 一个CircleCI账户
  • 一个Heroku账户
  • 虽然不是强制性的,但你应该知道一些关于TypeScript的事情。

构建一个新的Nest.js应用程序的脚手架

要创建一个新的Nest.js应用程序,从终端导航到你的开发文件夹的根,并运行以下命令。

nest new nest-heroku-demo

你会被提示选择你喜欢的软件包管理器。选择npm ,然后在键盘上点击ENTER ,继续。一个新的Nest.js应用程序将在一个名为nest-heroku-demo 的文件夹中创建,其所有的依赖将被安装。

一旦安装过程完成,移动到新创建的项目文件夹,用以下命令运行应用程序。

// move into the project
cd nest-heroku-demo

// start the server
npm run start:dev

你可以在默认端口3000 ,查看欢迎页面。

Default Page

创建演示应用程序

我们将快速创建一个基本的Nest.js应用程序,它有一个单一的端点,将被用来渲染产品列表。为了保持简单,我们将创建一个模拟的产品列表,并将其作为一个响应返回。要开始,用CTRL + C 停止应用程序在终端上的运行,并在你选择的代码编辑器中打开该项目。接下来,在src 文件夹中创建一个名为mock 的文件夹。在其中,创建一个名为products.mock.ts 的文件。将以下内容粘贴到该文件中(src/mock/products.mock.ts)。

export const PRODUCTS = [
  {
    id: 1,
    name: "First product",
    description: "This is the description for the first product",
    price: "200",
  },
  {
    id: 2,
    name: "Second product",
    description: "This is the description for the second product",
    price: "500",
  },
  {
    id: 3,
    name: "Third product",
    description: "This is the description for the third product",
    price: "800",
  },
  {
    id: 4,
    name: "Fourth product",
    description: "This is the description for the fourth product",
    price: "100",
  },
  {
    id: 5,
    name: "Fifth product",
    description: "This is the description for the fifth product",
    price: "250",
  },
];

一旦向/products 端点发送HTTP GET请求,这里导出的产品列表将作为响应返回。我们将在稍后讨论关于这个端点的更多细节。

设置一个服务

我们将使用默认的AppService 来返回产品列表。用以下代码替换src/app.service.ts 的内容。

import { Injectable } from "@nestjs/common";
import { PRODUCTS } from "./mock/products.mock";

@Injectable()
export class AppService {
  products = PRODUCTS;

  async getProducts() {
    return await this.products;
  }
}

在上面的文件中,我们从模拟文件中导入PRODUCTS ,并在getProducts() 方法中返回列表。

创建产品端点

接下来,我们将在默认的AppController 中创建/products 端点。要做到这一点,请导航到src/app.controller.ts 文件并将其内容替换为以下内容。

import { Controller, Get } from "@nestjs/common";
import { AppService } from "./app.service";

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get("/products")
  getProducts() {
    return this.appService.getProducts();
  }
}

AppService 已经被默认注入到这个控制器中。在这里,我们创建了一个名为getProducts 的新方法,前缀为/products ,并在AppService中调用getProducts() 方法。

运行应用程序

在项目的根目录下,用npm run start:dev ,再次启动应用程序,并导航到http://localhost:3000/products 。你会看到一个页面,显示我们模拟的产品的JSON列表。

Product List on Localhost

注意我安装了一个扩展来美化JSON。

推送到GitHub

请参阅本指南,了解如何将项目推送到GitHub

创建一个Heroku应用

设置一个Heroku应用程序是部署的必要条件。这有助于Heroku准备接收你的源代码。要开始了。

  • 登录到Heroku
  • 转到你的仪表板
  • 点击新建
  • 选择创建新的应用程序

你将被转到一个页面,在那里你将为你的应用程序输入基本细节。输入首选名称。

Create Heroku app

我将应用程序命名为nest-heroku-demo 。Heroku应用程序的名称需要是唯一的,所以请随意使用您认为合适的任何名称,然后点击创建应用程序。为了使CircleCI能够唯一地识别我们的Heroku应用程序并自动进行部署,我们需要创建环境变量。这将是我们刚刚创建的应用程序的名称和我们Heroku账户的API密钥。要查看您的Heroku API密钥,请点击您的个人资料图片,从下拉菜单中选择账户设置

Account Settings

这将带你到一个页面来管理你的账户。确保选择了 "账户"标签,向下滚动到API密钥部分。

API Key section

点击**"揭示 "**以查看API密钥,然后复制它。保存好它,因为我们以后会需要它。

为持续部署添加CircleCI配置

在本节中,我们将创建一个CircleCI配置文件,我们将为我们的应用程序编写部署脚本。要做到这一点,在应用程序的根部创建一个文件夹,名称为.circleci 。然后在其中创建一个文件,将其称为config.yml 。把下面的代码粘贴到这个新文件中。

version: 2.1
orbs:
  heroku: circleci/heroku@1.0.1
workflows:
  heroku_deploy:
    jobs:
      - heroku/deploy-via-git

上面的配置文件为这个项目指定了CircleCI的配置版本。在orbs 关键中,我们调用了在写作时可用的最新版本的Heroku orb。这个orb抽象了设置Heroku CLI的复杂性,因为它将被自动安装并用于将应用程序部署到Heroku。

在CircleCI上设置项目

现在我们已经创建了一个Heroku应用程序,并设置了配置以方便CircleCI将我们的Nest.js应用程序部署到Heroku,我们需要在CircleCI上配置我们的项目。使用链接的GitHub账户登录到您的CircleCI账户,该账户包含我们Nest.js应用程序的存储库。在项目页面,找到你的项目名称,并点击设置项目

Set up project

你会被提示有几个关于配置文件的选项。选择使用我的 repo 中的.circleci/config.yml 选项。输入你的代码在GitHub上存放的分支名称,然后点击设置项目按钮。

Select Config File

你的第一个工作流程将开始运行,但会失败。

Failed Build

现在,如果你点击上面页面中的工作heroku/deploy-via-git,你会看到部署不成功的详细原因。

Heroku Key Error

不要紧张,我们只需要做以下工作。

  • 将我们的Heroku应用程序的细节添加为环境变量
  • 在我们的项目中更新src/main.ts 中的端口
  • 创建一个Procfile

我们将在下一节中完成所有这些工作。

给CircleCI添加环境变量

为了让CircleCI在部署过程中对Heroku应用程序进行验证访问,我们需要从我们的Heroku账户中添加两个环境变量到我们的CircleCI管道。

点击管道页面上的项目设置,进入你的项目设置(确保你的项目是当前选定的项目)。

Project settings

在设置页面的侧边栏菜单上,点击环境变量

单击 "添加环境变量"。这将显示一个提示,你可以输入变量的名称和值。需要的变量是。

  • HEROKU_APP_NAME:先前创建的Heroku应用程序的名称
  • HEROKU_API_KEY:从你的Heroku账户仪表盘上获得的Heroku API密钥。

Environment variable page

我们几乎已经完成了自动部署应用程序所需的所有配置。

更新应用程序中的端口

在代码库中,我们需要更新main.ts ,选择使用固定端口或动态分配的值。这是因为Heroku经常为每个新的应用程序动态分配一个端口,所以设置一个固定值(Nest.js应用程序的默认值)会导致错误。打开src/main.ts ,更新其内容,如下图所示。

import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(process.env.PORT || 3000); // update this line
}
bootstrap();

有了这个选项,应用程序既可以在3000 的固定端口上运行,也可以在.env 文件中指定的任何动态端口上运行。

创建一个Procfile

最后,你需要在你的应用程序的根目录下创建一个名为Procfile 的新文件,并在其中粘贴以下内容。

web: npm run start:prod

这个文件告诉Heroku将在启动时用于执行应用程序的命令。

保存该文件,并将你的修改推送到GitHub仓库。现在观察你的CircleCI仪表板,看看部署的进展。

Deployment success status

我们项目的CircleCI管道的状态显示,构建成功,我们的应用程序已经被部署。你可以通过导航到Heroku为应用程序生成的链接来确认这一点。URL的格式总是一样的:https://YOUR_HEROKU_APP_NAME.herokuapp.com/ 。你也可以查看我的运行实例的端点

Heroku App

祝贺你!你刚刚部署了一个Nest.js应用程序。你刚刚部署了一个Nest.js应用程序到Heroku。

总结

在本教程中,我们能够建立一个简单的Nest.js应用程序,设置一个Heroku应用程序,并自动将我们的Nest.js应用程序部署到Heroku。这个项目的完整源代码可以在GitHub上找到。