本文首發於個人我的博客:高效前端項目自動化構建部署實踐——使用webhook鉤子運維,歡迎你們來訪問哦!前端
最近訪問個人博客網站的時候,我發現常常會出現打不開的狀況,個人博客是搭載在coding的coding pages服務上的,仔細檢查了coding服務上的代碼,發現沒什麼毛病,應該就是coding pages的服務器不穩定形成的,因爲最近在投遞簡歷,這個狀況也給我形成了必定的困擾,考慮到要給招聘者良好的瀏覽體驗,我決定要優化一下本身的博客網站運行環境了。node
個人優化思路就是將網站文件放到我本身的服務器上。起初我打算使用Hexo的ftp部署相關的插件來完成,當我運行hexo d
的時候,文件會自動上傳到服務器端,我這樣試着弄了以後發現因爲ftp協議的特性,在傳大量的文件的時候,沒法充分利用網絡帶寬,所以形成了速度很是慢的狀況。這種狀況只能將網站文件打包壓縮再上傳,而後在服務器端解壓才能解決。想了想,我以爲這樣太複雜又累贅,實在是不能體現我代碼潔癖的風格,拒絕拒絕!git
我在以前實習公司裏,有見同事用過webhook這玩意兒,瞭解過其運做方法和做用。又查了一下相關資料(下爲Github解釋):web
Webhooks allow you to build or set up integrations, such as GitHub Apps or OAuth Apps, which subscribe to certain events on GitHub.com. When one of those events is triggered, we'll send a HTTP POST payload to the webhook's configured URL. Webhooks can be used to update an external issue tracker, trigger CI builds, update a backup mirror, or even deploy to your production server. You're only limited by your imagination.shell
簡單來講就是WebHooks可用於更新外部問題跟蹤器、觸發CI構建、更新備份鏡像,甚至部署到生產服務器。這對於我目前的需求徹底匹配呀,因而新的思路來了——在服務器端克隆下本身的博客項目並安裝依賴,在coding服務上設置相應的webhook鉤子,在服務器端編寫接受webhook請求的回調方法,在回調方法裏執行構建相關的命令。這樣就不用把文件傳來傳去了,簡潔明瞭,開始搞!npm
在服務器上合適的位置克隆下本身的項目文件,並安裝好依賴,我這裏是hexo博客項目,因此還得全局安裝hexo依賴。後端
編寫接收webhook回調的服務,我這裏是用node.js寫的,你也可使用其餘後端語言,只要能執行shell命令就行。 在服務端合適的位置編寫webhook.js以下:安全
const http = require('http')
const { exec } = require('child_process')
const PORT = 9999 // 服務端口
const path = '/www/wwwroot/projects/xxxxxxx/' // 這裏是服務器端,此項目的文件地址
const commands = [
'cd ' + path,
'git pull',
'yarn dep', // 這個命令是我hexo項目編譯的命令
'rm -rf ../../hexo-blog/', // 刪除原來的文件
'mv ' + path + 'public/ ../../hexo-blog/' // 將編譯的文件放入網站項目文件夾
].join(' && ') // 這裏寫依次要在服務器上執行的命令
var deployServer = http.createServer(function(req, res) {
if (req.url.search(/deploy\/?$/i) > 0) { // 這裏作了個deploy的標記,以防用戶訪問此網址無心出發命令
let work = exec(commands, {
maxBuffer: 5000 * 1024, // 默認 200 * 1024
}, function(err, out) {
if (!err) {
res.writeHead(200)
res.end('Deploy Done.')
}
})
work.stdout.on('data', function(data) {
console.log('stdout: ' + data)
})
work.stderr.on('data', function(data) {
res.writeHead(500)
res.end('Server Internal Error.')
console.log('stderr: ' + data)
})
} else {
res.writeHead(404)
res.end('Not Found.')
}
})
deployServer.listen(PORT)
複製代碼
代碼很短很簡單,重點就是要調用node的子進程來執行命令。有個坑要注意,使用子進程時,在回調函數裏的打印是不會輸出到控制檯的,須要將當前執行過程設爲一個變量,經過其stdout和stderr的data監聽來獲取打印輸出。另外,exec在執行時會在內存中建一個buffer來緩衝組合全部的輸出數據,而maxBuffer則是指定該buffer大小的屬性。若是輸出超過指定的大小則會報 maxBuffer exceeded 的錯誤,這也是很常見的錯誤,因此咱們須要加大其maxBuffer。bash
寫好服務端代碼後,咱們ssh鏈接服務器,執行node webhook.js
將其啓動並不要關閉,以備後面調試,而且要注意你設置的端口在服務器安全組裏已經打開過了,或者你也可使用Nginx反向代理到80端口開啓另外一個服務,這裏就不細說了,目的就是要讓外網可以訪問到此服務。服務器
在Git項目管理的設置裏開啓並設置webhook服務
http://你的服務器地址:剛纔設置的端口/deploy
,令牌則是發送webhook時,客服端作的記號,也是起到防止惡意或無心請求到webhook服務的做用,若是設置了令牌,根據Git服務端的不一樣,會發送不一樣的令牌格式,通常是放在請求頭的自定義參數裏,咱們須要在服務端接收請求的方法裏進行處理,這裏再也不作演示。 若是設置完成,系統會自動發送檢測命令來出發webhook回調。
這時咱們查看網站對應的文件,會發現已經更新了!這時設置好對應的網站服務,就能夠正常訪問咱們的網站了。
要注意的是,臨時開啓的node進程會常常本身斷掉,咱們最好須要用pm2來管理node服務,PM2是node進程管理工具,能夠利用它來簡化不少node應用管理的繁瑣任務。 全局安裝pm2:
npm install -g pm2
複製代碼
開啓進程服務
pm2 start webhook.js
複製代碼
像這樣status爲online就是在正常運行了
webhook會監聽咱們的代碼推送,因此如今只用Git推送就能夠輕鬆地部署咱們的項目啦,大工告成!