Node.js的简单自动化构建管道
即使是简单的早期项目也能从自动化构建管道中受益。这里有一个用Node.js、Jenkins和Git建立CI/CD的简单方法。
作者 :Matthew Tyson
软件架构师,InfoWorld
对于企业应用来说,构建流程可能相当复杂,但即使是简单的早期项目也能从自动化构建管道中受益。本文介绍了一个快速部署的系统,用于使用Node.js、Jenkins和Git运行自动化构建、测试和部署管道。
你需要在你的系统上安装Git和Node/NPM来跟随。你还需要一个谷歌云平台(GCP)账户。(谷歌提供了一个慷慨的免费试用账户)。
[也在InfoWorld:寻找devops的理想]
这篇文章主要集中在devops方面,所以我们不会详细讨论Node.js应用如何工作。
我们将使用这里的简单启动器,创建一个 "Hello World "的Node.js应用。
开始吧
我们将建立一个构建管道,以响应对我们的 repo 的检查,因此从分叉项目开始。在你的浏览器中进入github.com/fhinkel/nod…,然后点击 "Fork",如图1所示。
图片1.分叉项目
现在你可以通过输入以下内容将你的项目克隆到你的本地系统。
git clone https://github.com/
(用你的用户名替换**)。
完成后,一个新的/nodejs-hello-world目录将被添加到你的文件系统中。
移动到该目录并输入npm install 。它只需要花一点时间来安装依赖性。
接下来,键入npm run start 。该应用程序现在应该正在运行,你可以去localhost:30查看简单的 "Hello World!"响应。
在GCP上安装Node应用程序
现在登录到GCP。如果你需要,你可以在这里创建一个免费账户。在GCP控制台中创建一个新的虚拟机实例,点击右上方的 "控制台",然后点击仪表板中的"->转到计算引擎"(或者你可以从左侧的滑块菜单中选择 "计算引擎")。
点击 "创建实例 "将出现实例配置屏幕,如图2所示。
图片2.创建一个实例
给实例取一个你能记住的名字。注意,我选择N1作为系列,Micro-1作为机器类型。这个机器配置文件属于免费级别(即使在试用期结束后),但它只适合于非常简单的使用,不适合于真实世界的开发或测试,当然也不适合生产。
确保选择 "允许默认的HTTP流量",这样平台会自动在路由中打开80端口。
一旦你点击 "创建实例 "按钮,该实例将出现在你的虚拟机列表中。现在你可以通过点击 "SSH "按钮SSH进入虚拟机。这对于快速获得实例的CLI是很方便的,不用处理密钥。
一旦外壳打开,你可以输入cat /etc/os-release ,看看你运行的是什么操作系统。在我的例子中,是Debian Buster。现在我们来安装 Git。
首先,运行sudo apt update ,让APT更新到最新。接下来,键入sudo apt install git 并接受提示,选择是。现在Git已经安装完毕。
现在你可以用git clone https://github.com//nodejs-hello-world 克隆应用程序,就像你在本地系统上做的那样。
cd 到新的应用程序目录。现在用 安装 Node/NPM 。sudo apt install nodejs npm
现在你可以用npm install ,然后用npm run start 来运行这个应用程序。然后,你应该能够通过从虚拟机列表中抓取其外部IP,并在浏览器中进入该应用。在我的例子中,这就是http://34.134.201.13/:80。请确保你访问的是HTTP,而不是HTTPS。
不建议在prod中直接运行Node应用。因此,修改package.json文件以包括以下脚本。
"start": "pm2 start index.js --watch"
现在用sudo npm install pm2 全局安装PM2包。一旦完成,你可以用sudo npm run start 来运行应用程序,PM2将负责对应用程序进行守护。你可以用sudo pm2 list 列出正在运行的应用程序,用sudo pm2 stop index 停止该应用程序。
这是一个足够好的生产环境的模拟,可以继续进行开发方面的工作。
在GCP上安装Jenkins
现在创建一个服务器,就像你在应用服务器上做的那样。在我的例子中,我将它命名为idg-ops。像你之前做的那样,SSH进入新的实例。
在Debian Buster上安装Jenkins的完整说明在这里。快速版本是安装Java,安装wget,安装Jenkins软件包的密钥,将Jenkins repo添加到Debian,最后再次更新APT。以下是这五个步骤。
sudo apt install default-jdk
在Jenkins服务器上安装Git
你还需要在Jenkins实例上安装Git和Node/NPM。
sudo apt install git
默认情况下,Jenkins在8080上运行,所以让我们在GCP防火墙规则中打开这个端口。在GCP控制台的左侧菜单中进入 "VPC网络->防火墙"。点击 "创建防火墙规则"。
将规则命名为 "Jenkins "并保留默认值,包括 "指定的目标标签"。添加 "jenkins"(全部小写)作为唯一的目标标签。在 "源IP范围 "中加入0.0.0.0/0以允许所有客户。最后,在 "指定的协议和端口 "中选择 "TCP "并将其设置为0.0.0.0/8080。
再次打开虚拟机实例列表(左侧菜单:"Compute Engine -> VM Instances"),选择你之前创建的Jenkins实例。现在你只需要添加Jenkins标签。点击 "编辑",在标签栏中添加 "Jenkins"。
现在,如果你导航到你的Jenkins实例的IP地址,即8080,你就会看到Jenkins的登陆页面,如图3所示。
图3.Jenkins登陆页面
正如该页面告诉你的,你需要找到日志来获得管理密码。(这可以确保你是有权限进入服务器所运行的系统的人)。在Jenkins服务器上,打开/var/,抓住你在那里看到的密码,如清单1所示。
清单1.日志中的Jenkins密码
*************************************************************
一旦你回到浏览器并插入你的密码,你就可以开始配置Jenkins。为了本文的目的,你可以只选择 "安装推荐的插件"。在真实世界的情况下,你会花时间准确挑选你需要的东西。
当Jenkins完成运行其默认安装时,它将提示你创建一个管理员用户--继续做吧。最后,Jenkins会要求你提供安装的绝对URL,你可以让它保持原样,用它检测到的IP和端口。
点击 "New Job",给它起个名字(我用了 "nodejs")。然后点击 "Freestyle Project "和 "OK"。
配置GitHub webhook到Jenkins
先把Jenkins放在一边,跳到你的GitHub账户,进入nodejs-hello-world项目,点击 "设置 "标签。在左边的菜单上,选择 "webhooks"。在webhooks详细界面,点击 "添加webhook"。webhook允许GitHub在事件发生时POST到一个URL。
对于webhook的URL,使用你的Jenkins安装的URL,后面加上/github-webhook。在我的例子中,这个URL是http://35.223.18.153:8080/github-webhook。将 "内容类型 "设置为 "application/json"。
在 "让我选择 "下,你可以使用多种事件类型来细化导致webhook运行的具体原因,但现在我们只使用 "推送",让事情保持原样。继续并点击 "添加webhook"。
现在返回到Jenkins。如果你需要的话,重新登录,并选择你先前创建的项目。点击左边的 "配置"。转到 "源代码管理 "部分,选择 "Git"。现在把你的Git repo的URL放在URL栏里。(在我的例子中是github.com/MTyson/node…
Jenkins 对 Git 的 URL 很敏感
Jenkins会使用你放在项目的Git配置中的URL,与来自GitHub的webhook推送进行匹配。
密切注意这些情况是否匹配。如果你看到Jenkins服务器上的日志确认了推送,但没有看到构建启动,请仔细检查URL。(Jenkins的日志条目会像 "2021-05-22 19:34:26.515+0000 [id=18] INFO o.j.p.g.w.s.DefaultPushGHEventSubscriber#onEvent:收到了来自140.82.115.154的推送事件github.com/MTyson/node… ⇒ http://35.223.18.153:8080/github-webhook/"。)
测试集成
现在你可以去你的本地系统上的项目并测试集成。打开index.js,将 "Hello World!"信息改为 "Greetings!"
现在用git add index.js 添加修改,用git commit -m "hook test" 提交,用git push origin master 推送到 repo。
你可以通过访问左边的 "GitHub Hook Log "来验证Webhook的运行,在那里你应该看到一个类似于图4的条目。
图片4.成功的 Git 钩子构建运行
你还会看到,如果你回到仪表板,项目现在显示的是最近成功的构建。(如果构建失败了,请确保你在Jenkins服务器上安装了Git)。
在生产系统中,每当有提交到master/main的时候,你就会对项目运行测试。你可以通过进入项目配置,点击 "Add a Build Step",创建一个shell命令,运行npm install ,然后是npm run test ,或者你可以创建shell脚本来满足更多的需求。
如果你修改package.json测试脚本,给出一个0的退出代码(将exit 1改为exit 0),那么你就可以模拟测试通过。
一旦测试通过,你要把验证后的构建推送到生产中。
回到Jenkins服务器的SSH shell。现在给Jenkins安装时为你创建的 "jenkins "用户设置一个密码:sudo passwd jenkins 。切换到该用户:su jenkins 。
现在为该用户生成一个密钥,它将用于对prod服务器进行验证:ssh-keygen -t rsa 。你可以接受默认值,注意在现实世界中你会使用口令。
仍然在Jenkins服务器上,输入命令。
ssh-copy-id
(在我的例子中,这是ssh-copy-id matthewcarltyson@34.134.201.13 。)
ssh-copy-id工具将把公钥复制到Node.js服务器上。
完成后,你应该能够直接从Jenkins机器上SSH到Node机器上。
ssh
(在我的例子中,ssh matthewcarltyson@34.134.201.13 。)
这意味着Jenkins服务器上的jenkins用户现在可以在没有密码的情况下SSH到Node生产服务器上。
作为最后一步,我们将创建一个shell脚本构建步骤,在测试构建步骤之后触发。如果测试通过,这个步骤将通过SSH进入Node服务器,从Git上获取最新的内容,然后重新启动服务器,如清单2所示。
清单 2.构建步骤。拉取最新版本,重启服务器
ssh matthewcarltyson@34.134.201.13 <<EOF
清单2工作得很好,除了我们接下来要解决的一个常见问题:Jenkins用户使用普通用户(在我的例子中是matthewcarltyson)来SSH到Node服务器并重启应用。这很好,因为你不想以root身份运行应用程序(安全性不好)。但在Linux中,你不能以普通用户的身份监听80端口。所以要做以下工作。
- 停止运行中的服务器。
sudo pm2 delete index - 以一个正常用户的身份启动服务器。
pm2 start index.js - 转到GCP控制台,为Node.js虚拟机实例添加一个名为 "nodejs "的VPC网络标签。
- 在GCP控制台,创建一个网络防火墙规则,允许TCP:80进入 "nodejs "标签。
- 在Node.js服务器命令行中,将请求从80重新路由到8080。
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT - 在你的本地机器上,将index.js改为监听8080端口,而不是80端口,然后签入。
现在,当你签入项目的变化时,Jenkins会自动构建并运行测试,更新生产实例,并在监听80端口时重新启动。
[紧跟软件开发的最新发展。订阅InfoWorld第一视角通讯]
CI/CD万岁
我们的Node.js应用的构建管线展示了devops CI/CD管线的许多关键元素。这并不是唯一的方法。最好的方法是由项目的需求决定的。
特别是,我们在本文中所说的 "生产",在一个更大规模的系统中,实际上是 "测试 "或 "QA"。只有在经过人工验证后,构建才会被推广到生产。
另外,我们可以考虑构建应用程序,在上面运行自动测试,然后将实际的构建复制到下一个阶段,从而省去构建步骤。
对于更稳健的要求,经过验证的构建一旦积极运行,将通过重新路由的网络流量接管负载。在重载的微服务中,这可以通过API网关逐步完成。
资源
- 如何使用SSH公钥认证
- 如何用Jenkins为Node.js应用建立CI/CD管道(在DigitalOcean上)。
- 你永远都不应该在生产中直接针对Node.js运行。也许吧。(PM2教程)
- 如何将你的GitHub仓库整合到你的Jenkins项目中去
相关的。
马修-泰森是黑马集团的创始人。他相信以人为本的技术。在不弹吉他的时候,Matt会去野外和哲学的腹地探险。自2007年以来,他一直为JavaWorld撰写文章。
关注
Copyright © 2022 IDG Communications, Inc.