https://segmentfault.com/a/1190000007892407javascript
安装nodejs建议直接下载二进制包,把官网上的64位二进制版本下载地址复制下来,执行php
wget https://nodejs.org/dist/v6.9.2/node-v6.9.2-linux-x64.tar.xz
html
xz
格式的文件按照如下命令解压:java
xz -d xxx.tar.xz
将 xxx.tar.xz解压成 xxx.tarnode
tar xvf xxx.tar
来解包linux
解压以后把目录拷贝到/usr/local/node
目录下laravel
cp ~/node_v**** /usr/local/node
git
为了方便全局启动须要在/usr/local/bin
下建立文件软链接github
ln -s /usr/local/node/bin/npm /usr/local/bin
web
ln -s /usr/local/node/bin/node /usr/local/bin
执行完毕以后就能够全局使用npm
和node
命令了。
因为网络问题,国内可使用阿里NPM镜像cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org
而后一般
/usr/bin
下面的都是系统预装的可执行程序,会随着系统升级而改变/usr/local/bin
目录是给用户放置本身的可执行程序的地方,推荐放在这里,不会被系统升级而覆盖同名文件.若是两个目录下有相同的可执行程序,谁优先执行受到PATH
环境变量的影响.
这里咱们要实现远程http调用以后能够启动shell脚本,因此咱们先编写部署脚本,因为这个项目个人开发环境和测试环境的配置文件不同,因此将git目录和部署目录分开了。这样就须要两个目录之间的单向同步
,这里我采用的方案是rsync
,虽然diff
也能实现文件夹比对,可是同步过程复杂,须要手动分析目录变更。
这个项目的框架是laravel
,xxx_git
是源码目录,xxx
是部署目录,具体状况能够调整。
这里咱们对于目录采用rsync
单向同步,对单文件采用cp
直接覆盖方式。
#!/bin/bash cd /home/wwwroot/xxx_git git pull origin master cp /home/wwwroot/xxx_git/composer.json /home/wwwroot/xxx/composer.json cp /home/wwwroot/xxx_git/composer.lock /home/wwwroot/xxx/composer.lock cp /home/wwwroot/xxx_git/_ide_helper.php /home/wwwroot/xxx/_ide_helper.php rsync --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/resources rsync --delete -avzp /home/wwwroot/xxx_git/resources/views /home/wwwroot/xxx/resources
脚本编写完毕以后执行下面的命令赋予执行能力
chmod +x ./my_sync.sh.sh
rsync参数:
-a
:表示归档模式,用递归方式传输文件-v
:详细输出-z
:传输时对文件进行压缩处理-r
:对子目录进行递归-t
:保持文件的时间信息-p
:保持文件的权限-o
:保持文件的属主信息-g
:保持文件的属组信息--delete
:表示以服务端为基准进行同步,保持服务端的目录文件和客户端的彻底一致--progress
:用于显示数据同步的过程--exclude
:排除不须要同步的目录或者文件
这里我采用了gitos上面的webhoos,其余的gitlab、github大同小异。
OSChina的webhook可见这里
这里我采用了express + child_process
解决调用问题,这个过程就比较简单了,这里面须要注意的是检测提交push
操做的是否是master
分之,其余分之的提交使不处理的。
这里exec
和req.send()
是没有回调关系的,因此服务器webhook时候不会超时。另外这里还实现了脚本运行的日志记录,能够针对每次部署来查看具体文件变动状况。
var express = require('express'); var app = express(); var cp = require('child_process'); var bodyParser = require('body-parser'); var jsonParser = bodyParser.json(); var moment = require('moment'); app.post('/git' , jsonParser ,function(req , res){ var json = req.body; if(json.password == 'xxxx'){ if (json.ref == 'refs/heads/master'){ var logName = (moment().format('YYYY-MM-DD_HH:m:s'))+'.log'; var command = '/home/nodejs/git_puber/my_sync.sh >> /home/nodejs/git_puber/' + logName; cp.exec(command, function(err, out, code) { if (err instanceof Error) { // res.writeHead(500) // res.end('Server Internal Error.') // throw err console.log(err + new Date()); }else{ console.log(out + new Date()); } }); }else{ console.log('not master branch'); } }else{ console.log('no auth pass'); } res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); res.send({result:('ok' + new Date()) , msg: 'your message has been delievered'}); // res.send(); }); app.listen(3000 , function(){ console.log('Server Is Running' + new Date()); });
nodejs是异步单线程,在一些状况下会出现异常退出的状况,为了保证服务常可用,咱们须要一个pm2
来保证程序的运行。
npm install pm2 -g
这里若是安装速度慢的话可使用
cnpm
安装。
执行pm2 start node app.js
便可之后台维护运行node程序。
pm2一些命令
pm2 list
pm2 stop all/[name]
pm2 start all/[name]
git checkout dev
切换到dev分支后修改文件
git commit
切换到主分支而后将dev分之合并过来
git checkout dev && git merge dev
提交以后服务器自动部署
git push