https://segmentfault.com/a/1190000007892407
安裝nodejs
安裝nodejs建議直接下載二進制包,把官網上的64位二進制版本下載地址復制下來,執行
wget https://nodejs.org/dist/v6.9.2/node-v6.9.2-linux-x64.tar.xz
xz
格式的文件按照以下命令解壓:
-
xz -d xxx.tar.xz
將 xxx.tar.xz解壓成 xxx.tar -
tar xvf xxx.tar
來解包
解壓之后把目錄拷貝到/usr/local/node
目錄下
cp ~/node_v**** /usr/local/node
為了方便全局啟動需要在/usr/local/bin
下創建文件軟連接
ln -s /usr/local/node/bin/npm /usr/local/bin
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
環境變量的影響.
編寫webhook代碼
部署腳本
這里我們要實現遠程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
:排除不需要同步的目錄或者文件
webhook接口編寫
這里我采用了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