如果你已经在软件开发领域工作了一段时间,特别是网络开发,那么你知道在历史上,将你的源代码部署到网络服务器上是多么的繁琐和紧张。大多数时候,这是通过使用文件传输协议(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 ,查看欢迎页面。

创建演示应用程序
我们将快速创建一个基本的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列表。

注意:我安装了一个扩展来美化JSON。
推送到GitHub
请参阅本指南,了解如何将项目推送到GitHub。
创建一个Heroku应用
设置一个Heroku应用程序是部署的必要条件。这有助于Heroku准备接收你的源代码。要开始了。
- 登录到Heroku
- 转到你的仪表板
- 点击新建
- 选择创建新的应用程序
你将被转到一个页面,在那里你将为你的应用程序输入基本细节。输入首选名称。

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

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

点击**"揭示 "**以查看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应用程序的存储库。在项目页面,找到你的项目名称,并点击设置项目。

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

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

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

不要紧张,我们只需要做以下工作。
- 将我们的Heroku应用程序的细节添加为环境变量
- 在我们的项目中更新
src/main.ts中的端口 - 创建一个
Procfile
我们将在下一节中完成所有这些工作。
给CircleCI添加环境变量
为了让CircleCI在部署过程中对Heroku应用程序进行验证访问,我们需要从我们的Heroku账户中添加两个环境变量到我们的CircleCI管道。
点击管道页面上的项目设置,进入你的项目设置(确保你的项目是当前选定的项目)。

在设置页面的侧边栏菜单上,点击环境变量。
单击 "添加环境变量"。这将显示一个提示,你可以输入变量的名称和值。需要的变量是。
HEROKU_APP_NAME:先前创建的Heroku应用程序的名称HEROKU_API_KEY:从你的Heroku账户仪表盘上获得的Heroku API密钥。

我们几乎已经完成了自动部署应用程序所需的所有配置。
更新应用程序中的端口
在代码库中,我们需要更新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仪表板,看看部署的进展。

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

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