当前位置: 首页 > 后端技术 > Node.js

创建一个简单的基于webhook的部署系统

时间:2023-04-03 17:32:37 Node.js

安装nodejs安装nodejs建议直接下载二进制包,复制官网64位二进制版本下载地址,执行wgethttps://nodejs.org/dist/v6.9.2/node-v6.9.2-linux-x64.tar.xzxz格式的文件按照如下命令解压:xz-dxxx.tar.xz将xxx.tar.xz解压成xxx.tar.xvfxxx.tar解压解压复制目录到/usr/local/node目录下cp~/node_v****/usr/local/node为了方便全局启动,需要在/下创建一个文件软链接usr/local/binln-s/usr/local/node/bin/npm/usr/local/binln-s/usr/local/node/bin/node/usr/local/bin执行后,npm和node命令可以全局使用。由于网络问题,国内可以使用阿里npm镜像。cnpmnpminstall-gcnpm--registry=https://registry.npm.taobao.org那么通常/usr/bin下的可执行程序都是系统预装的,后面会随着系统升级而改变/usr/local/bin目录是用户放置自己的可执行程序的地方。建议放在这里,同名文件不会被系统升级覆盖。如果两个目录下有相同的可执行程序,谁先执行,受PATH环境变量的影响。写一个webhook代码部署脚本这里我们可以在实现远程http调用后启动shell脚本,所以我们先写部署脚本,因为我这个项目的开发环境和测试环境的配置文件是不一样的,所以git目录和部署目录是分开的。这需要两个目录之间的单向同步。我在这里使用的解决方案是rsync。diff虽然也可以实现文件夹比较,但是同步过程比较复杂,需要人工分析目录变化。本项目框架为laravel,xxx_git为源码目录,xxx为部署目录,具体情况可以调整。这里我们对目录使用rsync单向同步,对单个文件使用cp直接覆盖。#!/bin/bashcd/home/wwwroot/xxx_gitgitpulloriginmastercp/home/wwwroot/xxx_git/composer.json/home/wwwroot/xxx/composer.jsoncp/home/wwwroot/xxx_git/composer.lock/home/wwwroot/xxx/composer.lockcp/home/wwwroot/xxx_git/_ide_helper.php/home/wwwroot/xxx/_ide_helper.phprsync--delete-avzp/home/wwwroot/xxx_git/app/home/wwwroot/xxx/rsync--delete-avzp/home/wwwroot/xxx_git/public/home/wwwroot/xxx/rsync--delete-avzp/home/wwwroot/xxx_git/resources/lang/home/wwwroot/xxx/resourcesrsync--delete-avzp/home/wwwroot/xxx_git/resources/views/home/wwwroot/xxx/resources脚本写好后,执行以下命令赋予执行能力chmod+x./my_sync.sh.shrsync参数:-a:表示归档模式,递归传输文件-v:详细输出-z:传输时压缩文件-r:递归子目录-t:保留文件时间信息-p:保留文件权限-o:保留文件所有者信息-g:保留文件属性组信息--delete:表示基于服务器进行同步,服务器目录文件与客户端完全一致--progress:用于显示数据同步的过程--exclude:排除不需要的目录或文件要同步写webhook接口,我用的是gitos上的webhoos,其他的gitlab和github都差不多。OSChina的webhook可以在这里看到。这里我使用express+child_process来解决调用问题。这个过程比较简单。这里需要注意的是,需要检查push操作的提交是否是master部分,提交的其他部分不做处理。这里exec和req.send()没有回调关系,所以serverwebhook不会超时。另外这里也实现了脚本运行的日志记录,每次部署都可以查看具体的文件变化。varexpress=require('express');varapp=express();varcp=require('child_process');varbodyParser=require('body-parser');varjsonParser=bodyParser.json();varmoment=require('moment');app.post('/git',jsonParser,function(req,res){varjson=req.body;if(json.password=='xxxx'){if(json.ref=='refs/heads/master'){varlogName=(moment().format('YYYY-MM-DD_HH:m:s'))+'.log';varcommand='/home/nodejs/git_puber/my_sync.sh>>/home/nodejs/git_puber/'+logName;cp.exec(command,function(err,out,code){if(errinstanceofError){//res.writeHead(500)//res.end('服务器内部错误。')//throwerrconsole.log(err+newDate());}else{console.log(out+newDate());}});}else{console.log('不是主分支');}}else{console.log('没有授权通过');}res.statusCode=200;res.setHeader('Content-Type','text/plain');res.send({result:('ok'+newDate()),msg:'您的消息已发送'});//res.send();});app.listen(3000,function(){console.log('服务器正在运行'+newDate());});参考扩展《exec与spawn方法的区别与陷阱》正在运行的监控程序nodejs是一个异步单线程,在某些情况下会异常退出。为了保证服务一直可用,我们需要一个pm2来保证程序的运行npminstallpm2-g如果安装速度慢,可以使用cnpm安装。执行pm2startnodeapp.js在后台维护运行node程序。pm2一些命令pm2listpm2stopall/[name]pm2startall/[name]自动部署gitcheckoutdev切换到dev分支并修改文件gitcommit切换到主分支然后合并dev分支gitcheckoutdev&&gitmergedev提交后服务器自动部署gitpush