Webhook 實踐 —— 自動部署


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格式的文件按照以下命令解壓:

  1. xz -d xxx.tar.xz 將 xxx.tar.xz解壓成 xxx.tar

  2. 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

執行完畢之后就可以全局使用npmnode命令了。

由於網絡問題,國內可以使用阿里NPM鏡像cnpm

npm install -g cnpm --registry=https://registry.npm.taobao.org

然后通常/usr/bin下面的都是系統預裝的可執行程序,會隨着系統升級而改變/usr/local/bin目錄是給用戶放置自己的可執行程序的地方,推薦放在這里,不會被系統升級而覆蓋同名文件.如果兩個目錄下有相同的可執行程序,誰優先執行受到PATH環境變量的影響.

編寫webhook代碼

部署腳本

這里我們要實現遠程http調用之后可以啟動shell腳本,所以我們先編寫部署腳本,由於這個項目我的開發環境和測試環境的配置文件不一樣,所以將git目錄和部署目錄分開了。這樣就需要兩個目錄之間的單向同步,這里我采用的方案是rsync,雖然diff也能實現文件夾比對,但是同步過程復雜,需要手動分析目錄變動。

這個項目的框架是laravelxxx_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分之,其他分之的提交使不處理的。

這里execreq.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()); });

參考延伸
《exec與spawn方法的區別與陷阱》

運行監控程序

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM