写点什么

Github Actions 实现 Node.js 项目的 CICD 环境搭建

作者:昆吾kw
  • 2022 年 8 月 06 日
  • 本文字数:5452 字

    阅读完需:约 18 分钟

Github Actions 实现 Node.js 项目的 CICD 环境搭建

前言

上篇文章《一文掌握 Node.js 的多进程模型和项目的部署》介绍了 Node.js 的多进程模型,以及如何以手动的方式将 Node.js 项目部署到服务器上。但是这种手动部署的方式实在是太落伍了。如今敏捷开发和 DevOps 的理念已深入人心,解放生产力、专注开发、自动化构建、测试、发布成了我们的追求。


本文将以 Github Actions 为例,介绍如何自动化部署一个简单的 Node 项目,主要内容有:


  • CI / CD 简介

  • Github Actions 是什么

  • 工作流配置文件的编写

  • 自动化部署 Node.js 项目

CICD

DevOps

DevOps 的理念并不复杂,简单说就是通过一套工具链,高效可靠的持续向用户交付产品。


DevOps 并没有标准化的规定,每个团队在落地实践时也不尽相同,但大体上它是这样一套流程:



它将软件产品开发的完整生命周期划分为几个不同的阶段,按照图里所描述的有:


  • Plan:计划

  • Code:开发

  • Build:构建

  • Test:测试

  • Release:发布

  • Deploy:部署

  • Operate:运维

  • Monitor:监控,并持续反馈,形成一个闭环


按照本文的写作背景,我们已经完成了代码的编写工作,接下来要进入的就是 Code 之后的阶段了。其中我们重点关注 Build、Test、Release 和 Deloy 这四个阶段,它们其实就是本文的重头戏 CI / CD。

CICD

CI,Continuous Integration持续集成,是指在开发过程中,持续的将开发者编写的代码多次的合并到主干上开发人员每次提交代码之后,都会触发自动构建和测试,以尽快发现问题。如果测试通过,则将新代码合并到主干上。如果测试失败,则反馈给开发人员,进行 bug 的修复。


上面 DevOps 流程图中,Build 和 Test 阶段,加起来就是 CI。


CDContinuous Delivery 持续交付Continuous Deploy 持续部署的简称。


交付和部署是两个容易混淆的概念。其实他们的含义并不十分相同。持续交付是指在完成 CI 中的自动化构建和测试之后,自动将代码发布到存储库。也就是说,持续交付的目的是生成一套可随时部署到生产环境的代码。持续部署则是持续交付的延伸,是指自动化的将代码部署到生产环境中。上图 DevOps 中的 Release 阶段就属于持续交付,Deploy 阶段就是持续部署。

CICD 工具

通过上面简单的介绍,我们知道 CICD 虽然美丽,但是要完成这样一套流程,具体要做的事情还是挺多的。市面上有很多优秀的 CICD 工具,可供我们使用:


  • Jenkins:基于 Java、跨平台、开源、独立的 CI/CD 工具,有大量的插件帮助完成软件开发过程的自动化构建、测试和部署。



  • Travis CI:基于云平台的、开源的 CICD 工具,可用于构建托管在 Github、Bitbucket、GitLab 上的项目。



  • Circle CI:与 Travis CI 同样是云平台构建,支持 Github、Bitbucket、GitLab。



  • Github Actions:使用云平台构建托管在 Github 之上的项目。


对于 Jenkins,需要先准备一台服务器安装好环境。而后三者全部是基于云平台的工具,我们只需要将代码托管到对应的平台,在让它们介入即可,使用起来会更加简单。


所以接下来我们以 Github Actions 为例进行演示。

Github Actions

简介


GitHub Actions 是微软推出的一款世界级(官网是这么说的)的 CI / CD 工具,可以帮助轻松实现软件开发工作流的自动化。如果代码托管在 Github 中,可以直接使用它来完成构建、测试和部署。

主要特点

  • 多平台:支持主流的 Linux、Windows、 macOS 虚拟机和容器,可以方便的项目的构建、测试和部署,也支持自定义运行器。

  • 多语言: 支持 Node.js、Python、Java、Ruby、PHP、Go、Rust、.NET 等语言,以您选择的语言构建、测试和部署应用程序。

  • 矩阵构建:使用矩阵工作流可同时跨多个操作系统和运行时版本进行测试,节省大量时间。

  • 实时日志:在仓库 Actions 面板中可以查看实时日志,以丰富的颜色和表情符号组织的日志可以一眼看出问题所在

  • 多容器测试:在工作流配置中添加 docker-compose 即可完成对 web 服务和数据库的测试

  • 社区支持:官方和社区有丰富的 Actions 可供选用,只要你能想到的需求,基本都能找到现成的方案

开源仓库免费使用


在 Github 上托管的开源仓库,可以免费使用该功能。


私有仓库,根据账号类型的不同,每月可享有 2000 分钟到 50000 分钟的免费时长,超出后会根据运行器(即构建我们的代码的虚拟机)的操作系统按时长收费。


核心概念

workflow 工作流

工作流是一种可配置的自动化过程,用于完成一项或多项工作。可以将其理解为完成一次 CI / CD 的 过程


我们可以在仓库中 .github/workflows 目录下创建一个 YAML 格式的配置文件,在配置文件中定义一个工作流。


配置文件的名字可以自定义,没有特殊要求。同时,还可以创建多个 YAML 文件来执行不同的任务集。

event 事件

配置文件中通过 on 属性来指定工作流执行的时机,可以在仓库中的事件(比如 push)触发时运行,也可以手动触发,或使用触发。


有关可使用的事件的更多介绍,可参阅“触发工作流程的事件”。

job 任务

一个工作流由一个或多个 jobs (任务集)组成,默认情况下任务集并行运行。


一个任务集可包含多个 job (任务),每个任务都需要指定一个 id。

runner 运行器

在一个任务中,需要通过 runs-on 指定任务运行的虚拟机环境。Github 提供了常用的不同版本 Ubuntu,Windows Server 和 MacOS 虚拟机环境可供选择。这个虚拟机在文档中叫作 “runner” 运行器。更多可供选择的运行器可访问“选择 GitHub 托管的运行器”。


Runner 对于不同的操作系统有不同的配置。Windows 和 Linux 虚拟机的硬件规格是:

  • 2 核 CPU (x86_64)

  • 7 GB RAM

  • 14 GB SSD 空间


MacOS 虚拟机的硬件规格:

  • 3 核 CPU (x86_64)

  • 14 GB RAM

  • 14 GB SSD 空间


除了使用 Github 提供的运行器,也可以使用自己的服务器作为一个运行器。


step 步骤

任务的具体工作由 steps 指定,它是由多个 step 分步组成的一组步骤集合。一个步骤可能是一个 shell 脚本,可能是一个动作(action)。

action 动作

Action 是 GitHub Actions 平台的一个自定义的应用,是最好用的特性之一。Action 就是将一些需要频繁多次执行的任务进行了封装。比如有一个最常用的一个 checkout action ,它可以 GitHub 中拉取你的仓库中的代码,被任务中后续的 step 使用。


Actions 市场有非常丰富的 action 可供使用,也可以实现符合自己需求的 action。


了解了 CI CD 的概念以及 Github Actions 的基本用法之后,我们来实践一下,加深理解。

开始实践

1. 创建 Github 仓库

使用 Gtihub Actions,项目必须托管在 Github 上。所以先建一个仓库。


2. 本地开发

本文的演示项目,依然是上文中的 express 项目,点击访问仓库。它主要提供了一个 /api/user 接口,返回 10 条 mock 的数据,不涉及到数据库操作。


初始目录结构如下:



初始化 git 环境:


git init
复制代码


在根目录新建 .gitignore 文件,或者从其他项目中拷贝一份使用。作用是将一些不需要上传至远程仓库的文件过滤掉:


node_modulespnpm-debug.log*
复制代码


然后将本地仓库关联到 Github 远程仓库:


# Github 默认主分支为 main,git 工具默认为 master,修改以统一git branch -M main  
git remote add origin git@github.com:hsyq/github-actions-express.git
复制代码


然后完成一次推送:


git add .git commit -m 'init'git push origin main
复制代码

3. 部署服务器的环境准备

Github Actions 为我们提供了自动化构建、测试的虚拟机环境,叫作 runner 运行器;项目最终要部署到我们自己的服务器上,所以需要先准备好服务器的环境,主要是:


  • 安装 node 环境

  • 安装 pm2 进程管理工具

  • nginx 端口转发


这三个步骤在上文中演示过了,所以不再过多介绍。不熟悉的朋友可以看下https://xie.infoq.cn/article/a34e1f2086ff03a26521321e0


主要作用就是,node 环境提供 express.js 项目运行的环境,pm2 来管理应用,保证应用的稳健运行,nginx 将请求从 80 端口转发到 express 项目的 3000 端口。


在服务器中我们同样使用了 pnpm 作为包管理工具,所以在安装好 node 之后,还需要再装一下 pnpm :


npm install -g pnpm
复制代码


其实这个环节还是有些繁琐,后面的文章我们会引入 docker 容器,在 Github Actions 中将应用打包成一个镜像,直接发布到服务器上创建容器,就不再需要这个环节了。

4. 配置仓库的 secrets

在工作流配置文件中会用到服务器地址,用户名密码等敏感信息。直接将它们暴露出去是很危险的操作。所以 Github 仓库提供了 Secrets,将一些敏感信息保存为加密后的环境变量,可供在工作流中通过 ${{ expression }} 的表达式使用。


进入仓库设置面板,来到 Security - Secrets -Actions,创建 repository secret:



演示项目的工作流配置文件需要三个 secret:


  • SERVER_HOST:部署服务器 IP

  • SERVER_USER:登录服务器的用户

  • SERVER_PASS:登录服务器的密码


本文案例中使用了传统的用户名密码的方式来登录服务器。 其实更推荐使用 SSH 密钥对的方式,会更加安全。后面的文章会进行演示。


分别创建这三个 secret:



5. 创建工作流配置文件

到目前为止,已经准备好了所需要的环境,开始创建一份工作流配置文件。


有两种方式,一是可以到仓库的 Actions 面板中,在线创建一个配置。二是直接在本地项目中编写,然后提交上去。

方式 1


选择一个 node.js 项目工作流的模板:




根据 action 的文档,完成我们自己的工作流配置文件的编写:



编辑好配置文件后,点击右上角的提交按钮:


方式 2

在项目根目录创建 .github/workflows/express.yml ,然后推送到仓库中。


本文使用第二种进行操作,每一步配置的具体含义已经写好了注释,方便理解:


# workflow 工作流的名字,自定义name: Express App
# 配置触发条件on: push: # 监听到 main 分支的 push 动作 branches: - main
# 工作流的任务集配置jobs: # 定义一个 job,id 为 build build: # 指定任务执行的运行器。latest 表示是 GitHub 提供的最新稳定映像,但可能不是操作系统供应商提供的最新版本。 runs-on: ubuntu-latest
# 定义 job 的具体步骤 steps: # 每一个 step 或者是执行一个 action,或者是执行一个命令 - name: Checkout # step 的名字,方便作日志排查 uses: actions/checkout@v3 # uses 表示该步骤使用一个 action 。斜线前面的 'actions' 表示这是官方的action
- name: Deploy to Server # 执行部署任务 uses: cross-the-world/ssh-scp-ssh-pipelines@latest with: host: ${{ secrets.SERVER_HOST }} user: ${{ secrets.SERVER_USER }} pass: ${{ secrets.SERVER_PASS }}
# 由于网路情况,很容易超时,设置为60s connect_timeout: 60s
# 将工作目录下的文件全部拷贝到部署服务器的工作目录 scp: | ./* => /www/github-actions-express # 完成拷贝后在部署服务器执行的命令:进入项目目录,安装生产依赖,并使用 pm2 管理 last_ssh: | cd /www/github-actions-express pnpm i --prod pm2 reload app.config.js
复制代码


一些说明:


  • checkout action:从 Github 仓库中 checkout 代码到 Github Actions 的 运行器中使用

  • ssh-scp-ssh-pipelines:一个第三方的 action,可以使用 scp 命令向其他服务器传输文件,配置中的作用就是将 Github Actions 运行器的项目文件拷贝到我们自己的服务器中,并执行一些命令


配至好工作流之后,只要向 main 分支执行 push 操作,Github Actions 就会开始工作。

6. 测试

将本地编写好的工作流配置文件,推送到远程仓库:


git add .git commit -m 'add workflow'git push origin main
复制代码


然后来到 Github 仓库中,切换到 Actions 面板,可以看到有一个工作流正在运行中:



根据工作流配置文件中事件的配置,Github Actions 监听到了 main 分支上的 push 动作,于是开始执行这个工作流。


这个过程持续的时间可能会比较长,甚至会出现超时出错,需要耐心等待一下。


等待工作流执行成功后,工作流状态变为绿色:



可以点开看一下,里面有整个构建任务运行的日志信息:




登录到云服务器中,切换到项目目录,发现项目已经从 Github 仓库传输到自己的服务器中了:


cd /www/github-actions-expressls
复制代码



由于在工作流中的配置,使用 action 传输完成后,会执行一些命令:


cd /www/github-actions-expresspnpm i --prodpm2 reload app.config.js
复制代码


所以现在项目应该已经由 pm2 托管了,打开 pm2 的管理面板:


pm2 list
复制代码



项目已经在正常运行中了。


本地浏览器访问接口 ironfan.site/api/users


小结

到这里,一个基于 Github Actions 实现的 Node.js 项目自动化部署的环境就搭建好了。


通过一张流程图来总结当前的这个流程:



在项目后续开发中,当本地的项目代码更新以后,只需要推送到 Github 仓库的 main 分支上,就能触发一次工作流的执行。Gtihub Actions 会帮我们把项目代码传输到服务器上,并在服务器上执行相关的命令,比如安装依赖,使用 pm2 重载应用。

总结

本文中,我们介绍了 CI / CD 的概念, 主要是帮助完成软件开发的自动化构建、测试和发布环节。


同时介绍了 Github Actions,它是由微软推出的功能非常强大的 CI / CD 工具。我们介绍了它的核心概念,以及常用的配置。


最后演示了使用 Github Actions 完成一个 Node.js 项目的自动化部署。


本次演示也有一些遗憾,虽然前文提到了 CI 中的自动化构建和测试。但是演示项目非常简单,无需构建,也没有准备测试环境,仅仅是演示了持续部署的环节。下次会准备一个 vue 项目,结合 docker 容器,完成一次完整 CI CD 的流程构建。


CI / CD 的内涵非常丰富,没办法通过一篇简单的文章就能介绍完整。我也是半路出家,文中如有描述不准确和错误的地方,请朋友们在评论区留言指出,感谢大家的指导!

发布于: 刚刚阅读数: 3
用户头像

昆吾kw

关注

还未添加个人签名 2020.10.21 加入

还未添加个人简介

评论

发布
暂无评论
Github Actions 实现 Node.js 项目的 CICD 环境搭建_nginx_昆吾kw_InfoQ写作社区