之前用Gitbook做了一个公司内部的文档中心,然后部署在了一台用作部门服务器的Mac上。因为公司用的svn,Mac上使用svn不方便所以就用的公司内部的私有GitLab仓库。之前一直都是在本地开发代码提交到GitLab上,再去服务机上更新代码,觉得每次这样实在太麻烦了,就去了解了下自动化部署,就发现了GitLab的Webhooks。
Webhooks是个在特定情况下触发的一种api,也叫钩子,GitLab中解释: Webhooks钩子用于在项目发生相关事件时通知外部服务器。Github也有类似的,叫Git Hooks。Git Hooks就是那些在Git执行特定事件(如commit、push、receive等)后触发运行的脚本。GitLab的webhooks跟git hook类似。也是当项目发生提交代码、提交tag等动作会自动去调用url,这个url可以是更新代码,或者其他操作。
设置Webhooks
登陆GitLab后,在项目Setting页面,找到Web Hooks:
URL就是需要部署到的服务器的网址,之后每次有相关事件发生的时候, GitLab 都会主动往这个地址发送一个 POST 请求,当然你也可以选择任何事件都发个 POST 通知你。下面会详说。然后选择触发该钩子的事件,GitLab支持五种事件。添加Web Hooks后,在下面的列表后面,还有个TEST HOOK ,可以测试这个钩子是否可以。
自动化部署代码
首先要写一个自动拉取GitLab上代码的shell脚本 deploy.sh
PROJECT_DIR='/data/projects/onlineDoc' # 等号左右不能有空格,这是你项目在服务器上的存储路径 echo 'start' cd $PROJECT_DIR echo 'pull code' git reset --hard origin/master && git clean -f git pull && git checkout master echo 'finished'
接下来就要写一个监听程序deploy.js去接受请求了,因为跑的node,所以可以找一个node的中间件,node-gitlab-webhook(Github也有类似的github-webhook-handler)。
首先起一个服务,createHandler里的path就是上面设置Web Hooks里的URL里的服务器ip后的path,监听端口可以自己设,这个端口也就是上面URL里的端口,比如我这里的是7777,URL最后就是 http:your server ip:7777/path
var http = require('http') var createHandler = require('node-gitlab-webhook') var handler = createHandler({ path: '/incoming', secret: '123456'}) // 一定要有密码参数,如果GitLab那边没有设置随便写就行 http.createServer(function (req, res) { handler(req, res, function (err) { res.statusCode = 404 res.end('no such location') }) }).listen(7777)
然后注册push事件:
handler.on('push', function (event) { console.log( 'Received a push event for %s to %s', event.payload.repository.name, event.payload.ref ) execFunc('sh ./deploy.sh') }) function execFunc(content) { var exec = require('child_process').exec exec(content, function(error, stdout, stderr) { if (error) { console.error('exec error:' + error) return } console.log('stdout:' + stdout) console.log('stderr:' + stderr) }) }
完整代码可以看 这里。
接下来就可以把服务跑起来了,为了防止node的服务自己挂掉导致不能访问文档中心,我又用了进程管理服务PM2
npm install pm2@latest -g npm start deploy.js
这样就算这段node代码某处出错挂了,它也会自动重新启动一个进程,保证服务仍可用。
到此GitLab的Webhooks自动化部署就完成了,以后只需要在本地提交代码,服务器就会自动更新代码并部署。