2020 年 9 月 17 日

使用 TypeScript、PostgreSQL 和 Prisma 的后端:CI 和部署

在本系列的第四部分中,我们将配置使用 GitHub Actions 的持续集成 (CI) 和持续部署 (CD),以测试后端并将其部署到 Heroku。

Backend with TypeScript, PostgreSQL & Prisma: CI & Deployment

介绍

本系列的目标是通过解决一个具体问题来探索和演示现代后端的不同模式、问题和架构:在线课程的评分系统。 选择这个问题是因为它具有多种关系类型,并且足够复杂,可以代表真实的用例。

上面的直播录像可用,内容与本文相同。

本系列将涵盖的内容

本系列将侧重于数据库在后端开发的各个方面的作用,涵盖

主题部分
数据建模第 1 部分
CRUD第 1 部分
聚合第 1 部分
REST API 层第 2 部分
验证第 2 部分
测试第 2 部分
无密码身份验证第 3 部分
授权第 3 部分
与外部 API 集成第 3 部分
持续集成第 4 部分(当前)
部署第 4 部分(当前)

在第一篇文章中,您为问题域设计了数据模型,并编写了一个种子脚本,该脚本使用Prisma Client将数据保存到数据库。

在本系列的第二篇文章中,您在第一篇文章中的数据模型和Prisma schema之上构建了REST API。 您使用 Hapi 构建 REST API,它允许通过 HTTP 请求对资源执行 CRUD 操作。

在本系列的第三篇文章中,您使用 JSON Web Tokens (JWT) 与 Hapi 实现了基于电子邮件的无密码身份验证和授权,以保护 REST API。 此外,您还实现了基于资源的授权,以定义允许用户执行的操作。

您今天将学到的内容

在本文中,您将通过定义一个工作流程来设置 GitHub Actions 作为 CI/CD 服务器,该工作流程运行测试并将后端部署到 Heroku,您将在 Heroku 上托管后端和 PostgreSQL 数据库。

Heroku 是平台即服务 (PaaS)。 与无服务器部署模型相比,使用 Heroku,即使没有向其发出请求,您的应用程序也将持续运行。 虽然无服务器具有许多优点,例如更低的成本和更少的操作开销,但这种方法避免了数据库连接抖动和冷启动的挑战,这些挑战在无服务器方法中很常见。

要了解有关使用 Prisma 的应用程序的部署范例之间权衡的更多信息,请查看Prisma 部署文档

注意: 在本指南中,您会找到各种检查点,使您能够验证是否正确执行了步骤。

前提条件

要使用 GitHub Action 将后端部署到 Heroku,您将需要以下内容

  • Heroku 帐户。
  • Heroku CLI 已安装。
  • 用于发送电子邮件的 SendGrid API 令牌,您在系列第 3 部分中创建了该令牌。

持续集成和持续部署

持续集成 (CI) 是一种技术,用于将各个开发人员的工作集成到主代码存储库中,以尽早发现集成错误并加速协作开发。 通常,CI 服务器连接到您的 Git 存储库,并且每次将提交推送到存储库时,CI 服务器都会运行。

持续部署 (CD) 是一种关注自动化部署过程的方法,以便可以快速且一致地部署更改。

虽然 CI 和 CD 关注不同的职责,但它们是相关的,并且通常使用相同的工具处理。 在本文中,您将使用 GitHub Actions 来处理 CI 和 CD。

持续集成流水线

通过持续集成,主要的构建块是流水线。 流水线是您定义的一组步骤,以确保您的更改不会引入任何错误或回归。 例如,流水线可能具有运行测试、代码检查器和 TypeScript 编译器的步骤。 如果其中一个步骤失败,CI 服务器将停止并将失败的步骤报告回 GitHub。

当在团队中使用拉取请求引入代码更改时,CI 服务器通常会配置为为每个拉取请求自动运行流水线。

您在之前的步骤中编写的测试通过模拟对 API 端点的请求来工作。 由于这些端点的处理程序与数据库交互,因此您将需要一个具有后端 schema 的 PostgreSQL 数据库,以用于测试期间。 在下一步中,您将配置 GitHub Actions 以运行测试数据库(在 CI 运行期间)并运行迁移,以便测试数据库与您的 Prisma schema 保持一致。

注意: CI 的质量仅与您编写的测试一样好。 如果您的测试覆盖率较低,则通过测试可能会产生虚假的信心感。

使用 GitHub Actions 定义工作流程

GitHub Actions 是一个自动化平台,可用于持续集成。 它提供了一个 API,用于根据 GitHub 中的事件编排工作流程,并且可以用于从 GitHub 构建、测试和部署您的代码。

要配置 GitHub Actions,您需要使用 yaml 定义工作流程。 可以将工作流程配置为在不同的存储库事件上运行,例如,当提交被推送到存储库或创建拉取请求时。

每个工作流程可以包含多个作业,每个作业定义多个步骤。 作业的每个步骤都是一个命令,并且可以访问正在测试的特定提交处的源代码。

注意: CI 服务对流水线使用不同的术语; 例如,GitHub Actions 使用术语工作流程来指代相同的事物。

在本文中,您将使用存储库中的grading-app 工作流程

让我们看一下工作流程

grading-app 工作流程有两个作业:testdeploy

test 作业将执行以下操作

  1. 检出存储库。
  2. 配置节点。
  3. 安装依赖项。
  4. 在使用 services 启动的测试数据库中创建数据库 schema。
  5. 运行测试。

注意: services 可用于运行其他服务。 在上面的测试作业中,它用于创建测试 PostgreSQL 数据库。

deploy 作业将执行以下操作

  1. 检出存储库
  2. 安装依赖项
  3. 针对生产数据库运行迁移
  4. 部署到 Heroku

注意: on: push 将为每次推送的提交触发工作流程。 if: github.event_name == 'push' && github.ref == 'refs/heads/master' 条件确保 deploy 作业仅针对 master 分支触发。

Fork 存储库并启用工作流程

首先 fork GitHub 存储库,以便您可以配置 GitHub actions。

注意: 如果您已经 fork 了存储库,请合并来自 origin 存储库 master 分支的更改

Fork 后,转到 Github 上的actions选项卡

通过单击启用按钮来启用工作流程

现在,当您将提交推送到存储库时,GitHub 将运行工作流程。

Heroku CLI 登录

确保您已使用 CLI 登录到 Heroku

创建 Heroku 应用程序

要将后端应用程序部署到 Heroku,您需要创建一个 Heroku 应用程序。 从克隆存储库的文件夹运行以下命令

注意: 使用您选择的唯一名称代替 YOUR_APP_NAME

检查点 Heroku CLI 应记录应用程序已成功创建

在 Heroku 上配置 PostgreSQL 数据库

使用以下命令创建数据库

检查点:要验证数据库是否已创建,您应该看到以下内容

注意: Heroku 将自动为应用程序运行时设置 DATABASE_URL 环境变量。 Prisma Client 将使用 DATABASE_URL,因为它与Prisma schema中配置的环境变量匹配。

在 GitHub 中定义构建时密钥

为了让 GitHub Actions 运行生产数据库迁移并将后端部署到 Heroku,您将创建在 workflow 中引用的四个密钥,如GitHub 中所述。

注意: 需要区分构建时密钥和运行时密钥。 构建时密钥将在 GitHub 中定义,并在 GitHub Actions 运行期间使用。 另一方面,运行时密钥将在 Heroku 中定义,并由后端使用。

密钥

  • HEROKU_APP_NAME:您在上一步中选择的应用程序名称。
  • HEROKU_EMAIL:您注册 Heroku 时使用的电子邮件。
  • HEROKU_API_KEY:Heroku API 密钥
  • DATABASE_URL:Heroku 上的生产 PostgreSQL URL,在部署之前运行生产数据库迁移时需要它。

获取生产 DATABASE_URL

要获取 Heroku 在配置数据库时设置的 DATABASE_URL,请使用以下 Heroku CLI 命令

检查点: 您应该在输出中看到 URL,例如 postgres://username:[email protected]:5432/dbname

获取 HEROKU_API_KEY

可以从您的 Heroku 帐户设置中检索 Heroku API 密钥

Heroku API key in the Heroku account settings

在 GitHub 中创建密钥

要创建四个密钥,请转到存储库设置并打开Secrets选项卡

GitHub repository secrets

单击New secret,使用名称字段作为密钥名称,例如 HEROKU_APP_NAME 并设置值

检查点: 创建四个密钥后,您应该看到以下内容

GitHub repository secrets

在 Heroku 上定义环境变量

后端需要三个密钥,这些密钥将在运行时作为环境变量传递给应用程序

  • SENDGRID_API_KEYSendGrid API 密钥
  • JWT_SECRET:用于签署 JWT 令牌的密钥。
  • DATABASE_URL:Heroku 自动设置的数据库连接 URL。

注意: 您可以通过在终端中运行以下命令来生成 JWT_SECRETnode -e "console.log(require('crypto').randomBytes(256).toString('base64'));"

要使用 Heroku CLI 设置它们,请使用以下命令

检查点: 要验证环境变量是否已设置,您应该看到以下内容

触发工作流程以运行测试和部署

配置工作流程、在 Heroku 上创建应用程序并设置所有密钥后,您现在可以触发工作流程以运行测试和部署。

要触发构建,请创建一个空提交并推送它

推送提交后,转到 GitHub 存储库的 Actions 选项卡,您应该看到以下内容

单击表中带有提交消息的第一行

查看 test 作业的日志

要查看 test 作业的日志,请单击 test,这将允许您查看每个步骤的日志。 例如,在下面的屏幕截图中,您可以查看测试结果

验证到 Heroku 的部署

要验证 deploy 作业是否成功部署到 Heroku,请单击左侧的 deploy 并展开 Deploy to Heroku 步骤。 您应该在日志末尾看到以下行

要从浏览器访问 API,请从克隆的存储库文件夹中使用以下 Heroku CLI 命令

这将打开浏览器,指向 https://YOUR_APP_NAME.herokuapp.com/

检查点:您应该在浏览器中看到 {"up":true},它由状态端点提供。

查看后端日志

要查看后端的日志,请从克隆的存储库文件夹中使用以下 Heroku CLI 命令

测试登录流程

要测试登录流程,您需要对 REST API 进行两次调用。

首先获取 API 的 URL

使用 curl 对登录端点进行 POST 调用

检查电子邮件中的 8 位令牌,然后进行第二次调用

检查点: 响应应具有 200 成功状态代码,并包含带有 JWT 令牌的 Authorization 标头

总结

您的后端现在已部署并正在运行。 做得好!

您通过定义 GitHub Actions 工作流程、创建 Heroku 应用程序、配置 PostgreSQL 数据库以及使用 GitHub Actions 将后端部署到 Heroku,配置了持续集成和部署。

当您通过提交到存储库并推送更改来引入新功能时,测试和 TypeScript 编译器将自动运行,如果成功,后端将被部署。

您可以通过进入 Heroku 仪表板来查看内存使用率、响应时间和吞吐量等指标。 这对于深入了解后端如何处理不同的流量非常有用。 例如,后端负载越大,响应时间可能会越慢。

通过将 TypeScript 与 Prisma Client 结合使用,您可以消除一类通常在运行时检测到并涉及调试的类型错误。

您可以在 GitHub 上找到后端的完整源代码。

虽然 Prisma 旨在使使用关系数据库变得容易,但了解底层数据库和 Heroku 特定详细信息 仍然很有用。

如果您有任何疑问,请随时在 Twitter 上联系。

不要错过下一篇文章!

注册 Prisma 新闻通讯