最近为博客申请了一个域名spacebound.xyz还在备案中,等备案完成就能通过域名访问本站,刚好手上有一台闲置的腾讯云服务器,就考虑将博客代码部署到服务器上。
服务器选择的是windows环境,.Net程序员后遗症+对Linux不熟 使用Nginx部署静态网站。按照传统的方式,在本地编辑、发布成静态资源以后还要远程桌面或者ftp/sftp上传至服务器,这样做太过麻烦,我想要更加自动化的方式实现。
经过一番资料查找后发现GitHub的WebHooks可以很方便的实现代码自动化管理,只要在GitHub相应库中设置好WebHooks,服务端使用NodeJs来构Webhook服务,就可以轻松的实现提交git时服务器自动更新代码完成部署
具体实现如下:

GitHub的WebHooks设置

打开你要进行自动化部署的项目的GiHub仓库地址,进入Settings设置页面,点击左侧的Webhooks
点击Add webhook,添加一个webhook Payload URL 填写你项目的域名或服务器IP地址加端口号,例如: https:www.spacebound.xyz:6666
Content type 选择application/json
Secret webhook请求时在head中附加的密钥,之后会使用到需记住。例如: test6666

服务端使用NodeJs构建WebHook服务

创建NodeJs服务

服务器需要安装NodeJs,然后执行命令

npm install http-server -g
npm install github-webhook-handler -g

来安装http-server和github-webhook-handler中间件,在项目根目录下新建webhook.js

var http = require('http')
var createHandler = require('github-webhook-handler')
var handler = createHandler({ path: '/', secret: 'test6666' })
// 上面的 secret 保持和 GitHub 后台设置的一致
http.createServer(function (req, res) {
  handler(req, res, function (err) {
    res.statusCode = 404
    res.end('no such location')
  })
}).listen(6666)
//监听6666端口
handler.on('error', function (err) {
  console.error('Error:', err.message)
})
handler.on('push', function (event) {
  console.log('Received a push event for %s to %s',
    event.payload.repository.name,
    event.payload.ref);
	
  const spawn = require('child_process').spawn;
    //const cmd = 'git pull origin master';
    //const p = spawn(cmd, [], {shell: true});
    const p = spawn('deploy.sh', [], {shell: true})

  p.stdout.on ('data', (data) => {
		console.log (data.toString ());
	});
})

其中

const spawn = require('child_process').spawn;
    //const cmd = 'git pull origin master';
    //const p = spawn(cmd, [], {shell: true});
    const p = spawn('deploy.sh', [], {shell: true})

  p.stdout.on ('data', (data) => {
		console.log (data.toString ());
	});


这个部分是使用NodeJs的子进程child_process来执行shell脚本。这个地方踩了很多坑,由于对NodeJs不是很熟只能现学现用,官方API虽然对这个方法参数名有详细注解,但对于实际参数怎么写没有提供示例。
百度上查到的教程和例子都千篇一律 强烈吐槽百度,只有介绍shell基础命令怎么使用,没有关于git命令和调用.sh文件的示例。最后还是在stackoverflow上的相关问题中找到了答案

创建Shell脚本

先在网站根目录创建Git文件控制,添加远程Git仓库地址

#!/bin/bash
git init
git remote add origin https://xxx.git 

然后创建deploy.sh,和webhook.js处于同一目录下

#!/bin/bash
echo "start deployment"
git pull origin master
git reset --hard master
echo "done"

到这里就可以使用nodejs webhook.js命令将服务启动。

使用pm2进行进程守护

PM2是node进程管理工具,可以利用它来简化很多node应用管理的繁琐任务,如性能监控、自动重启、负载均衡等,而且使用非常简单。引用

pm2安装

执行命令

npm i pm2 -g

启动

pm2 start webhook.js --watch -i 2

pm2在windows服务器下开启自动开启服务

在安装好pm2的基础上,执行命令安装pm2-windows-service和pm2-windows-startup中间件

npm install pm2-windows-service -g
npm install pm2-windows-startup -g

添加.pm2的系统环境变量

PM2_HOME=C:\Users\Administrator\.pm2(路径默认在当前用户下的.pm2)

以管理员身份运行cmd,执行以下命令安装服务

pm2-service-install

提示Perform environment setup?时选n,回车继续。此时PM2服务已安装成功并已启动,(如果没启动请自行到Windows服务处启动服务)名称为PM2

打开cmd,移动到项目更目录下,执行命令

pm2 start webhook.js -n myBlog
pm2 save


pm2 save 十分重要, 它保存当前pm2正在管理的NodeJS服务, 并在开机后恢复这些服务,保存路径为系统环境变量设置的PM2_HOME路径。
重启服务器后输入命令查看pm2列表,发现myBlog服务已启动,至此,开机自动启动配置完成。

pm2 list



结束语:该项hook技术不仅适用于Github、Gitlab、Gitee等线在上仓库,也可以在自己搭建的git服务器实现,在实际的项目中使用可以达到生产环境代码自动部署的目的。动手过程中有什么不清楚的地方可以在文章下方留言或者微信联系我,共同讨论 :)