如果你希望本地执行 git push 到git服务器后,在目标服务器上直接拉取代码并进行部署的话,可以参考下本教程。
背景
ui同学平时把素材包都放在 git.ui 的git仓库中,几个版本迭代下来,整个仓库的大小已经达到了1.7g,每次clone都很艰难...
直到有一天,有人在群里建议可以直接挂在服务直接访问...
思路
拆分这个需求,有两个点需要实现:
步骤1进一步拆分,从这两个角度出发,第一个点有很多实现方案,在这里罗列几种实现方案:
这里以第一种方案为例,来具体实现一下。
因此整个流程需要分成三端,客户端(新变更推送)、git服务器(git挂载服务器)、目标服务器(进行自动部署的服务器)。考虑到第二点,在仓库被push的时候,要自动触发消息。自然想到使用githook来处理( githook的介绍可以看这篇 )。但是githook中不管是客户端钩子还是服务端钩子都只能在客户端和服务端之间双向链接,因此需要使用git服务器的webhook功能(webhook介绍)。整个流程如下图:
实现
由上面思路流程,node服务需要区分请求的类型:
- GET请求:根据url进行静态文件重定向
- POST请求:收到webhook请求,执行脚本,拉取git仓库
关于静态文件部署,调研了两个npm包: st 和 serve-handler 。两者都可以进行静态资源部署,但是经测试,st对中文命名的目录名支持不好,会出现乱码,serve-handler对中文目录支持比较好,故选择serve-handler。
关于执行脚本拉取仓库,有两种方案推荐,一种是node执行脚本或执行命令行命令的方式child_process,利用子进程进行脚本的执行,另外一种是第三方的shelljs,是在 child_process 的基础上的封装,调用系统命令更简单。故选择第二种。
因此具体代码如下:
var http = require('http');// 静态文件部署var handler = require('serve-handler');// 执行 shell 命令var shell = require('shelljs');http.createServer(function(request, response) { var urlMethod = request.method; if(urlMethod === 'POST') { // 拿到POST请求,输出内容并执行git pull操作 console.log("POST request"); var cOntent= ""; request.on('data', function (chunk) { content += chunk; }); request.on('end', function () { response.writeHead(200, {"Content-Type": "text/plain"}); response.write("You've sent: " + content); response.end(); console.log("POST data:",content); }); try{ // 拉取最新代码 shell.exec("git pull"); console.log("POST success"); }catch(e) { console.log("POST fail"); } return; }else { // GET请求,直接调用serve-handler来静态资源重定向 console.log("GET request"); console.log("GET url", request.url); return handler(request, response, { "public": "git.ui" }); }}).listen(8080);console.log('Server started');在目标服务器上用pm2部署服务,同时在git服务器上设置webhook的触发地址,完成目标服务器的部署。
后续
后续可以注册服务和域名,将机器绑定域名,或利用现有服务配置Nginx映射。
大家有兴趣的可以试着实现以下第二种第三种访问静态文件的部署方案。