1. 前置條件
- 有一台自己的服務器。比如阿里雲,騰訊雲之類
- 有遠程倉庫能夠push代碼,pull代碼。比如github,或者碼雲
- 遠程倉庫有webhooks功能
2. 自動化部署流程圖
3. 構建流程
3-1. 服務器部署git環境
1. 安裝git
通過指令yum install git
安裝git
安裝按完成后可以看到
2. 設置ssh密鑰
通過以下指令創建密鑰,-C后面的內容,寫你的郵箱名字就行
ssh-keygen -t rsa -C "youreamil@163.com"
不需要密碼的話,一直回車就行了,然后可以得到兩個文件:id_rsa和id_rsa.pub
3. 添加ssh密鑰
在github添加密鑰
在碼雲添加密鑰
4. 測試密鑰添加成功
github通過以下指令測試
ssh -T git@github.com
碼雲通過以下指令測試
ssh -T git@gitee.com
碼雲測試通過會顯示 success,如下圖所示
5. clone遠程代碼倉庫到服務器
接着找到遠程倉庫代碼的ssh地址
這個時候需要建立一個文件夾mkdir web
,然后進入web文件夾中,通過git clone
指令把遠程倉庫拷貝到服務器的web目錄下
git clone git@gitee.com:XXXXXX.git
clone結束后,web文件夾下已經有了你的項目,這里yourprogram就是你的clone下來的項目文件夾,我們通過cd yourprogram
,我們可以看到服務器里面已經有了代碼內容
3-2. 服務器部署node環境
1. 安裝nvm
在服務器中輸入以下兩種指令都行
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
2. 通過nvm安裝node
nvm install v10.20.1
安裝完成后,我們通過指令node -v
和 npm -v
確認使用這個版本的node
具體的安裝過程可以看我的這篇文章linux服務器通過nvm安裝node環境
3. 安裝pm2
通過以下指令全局安裝pm2
npm install -g pm2
通過pm2 list
查看當前node進程為0
3-3. 創建webhook用服務后端
我們使用 NodeJS 創建 webhook 服務后端,后端代碼保存在 webhook文件也就是index.js中,調用 deploy.sh 來發布,因此需要與 deploy.sh 文件在同一級目錄中,監聽 http://127.0.0.1:6666/webhook:
git_webhook目錄結構如下
deploy.sh
node_modules
package.json
index.js
目錄結構就是這樣
1.初始化node
首先我們通過指令mkdir git_webhook
新建一個文件夾git_webhook,然后通過一下指令初始化node
ps: git_webhook文件夾可以放在/opt目錄下
npm init
2. 安裝node包
Github webhooks需要跟我們的服務器進行通信,確保是可以推送到我們的服務器,所以會發送一個帶有X-Hub-Signature的POST請求,為了方便我們直接用第三方的庫github-webhook-handler來接收參數並且做監聽事件的處理等工作
npm i -S github-webhook-handler
同上,這個是碼雲用的,原理一樣
npm i —S gitee-webhook-middleware
3. 建立index.js
接下來就是構建起一個能夠接收遠程倉庫post請求的服務,這同樣也很簡單,我們可以通過上面下載的包github-webhook-handler的幫助,快速建立起這樣一個服務
ps: index.js中的secret就是webhooks設置中的key
通過以下指令創建並寫入index
vim index.js
我們構建入口文件代碼(git用)
var http = require('http');
var spawn = require('child_process').spawn;
// git用
// secret 保持和 GitHub 后台設置的一致
var handler = createHandler({ path: '/webhook', secret: 'webhook' });
var createHandler = require('github-webhook-handler');
// 碼雲用
// var createHandler = require('gitee-webhook-middleware');
// var handler = createHandler({ path: '/webhook', token: 'webhook' });
http.createServer(function (req, res) {
handler(req, res, function (err) {
res.statusCode = 404;
res.end('no such location');
})
}).listen(6666);
console.log('listen at prot 6666')
handler.on('error', function (err) {
console.error('Error:', err.message)
});
// 修改push監聽事件,用來啟動腳本文件
//git是push ,而碼雲是Push Hook
handler.on('push', function (event) {
console.log('Received a push event for %s to %s',
event.payload.repository.name,
event.payload.ref);
runCommand('sh', ['./deploy.sh'], function( txt ){
console.log(txt);
});
});
// 啟動腳本文件
function runCommand( cmd, args, callback ){
var child = spawn( cmd, args );
var resp = 'Deploy OK';
child.stdout.on('data', function( buffer ){ resp += buffer.toString(); });
child.stdout.on('end', function(){ callback( resp ) });
}
構建入口文件代碼(碼雲用)
var http = require('http');
var spawn = require('child_process').spawn;
// 碼雲用
// token 保持和 碼雲 后台設置的一致
var createHandler = require('gitee-webhook-middleware');
var handler = createHandler({ path: '/webhook', token: 'webhook' });
// git用
// var handler = createHandler({ path: '/webhook', secret: 'webhook' });
// var createHandler = require('github-webhook-handler');
// 上面的 secret 保持和 GitHub 后台設置的一致
http.createServer(function (req, res) {
handler(req, res, function (err) {
res.statusCode = 404;
res.end('no such location');
})
}).listen(6666);
console.log('listen at prot 6666')
handler.on('error', function (err) {
console.error('Error:', err.message)
});
// 閱讀上面代碼,你會發現handler監聽到push事件調用對應的函數,所以你要做的就是在函數中執行deploy.sh命令,你需要在index.js添加代碼
// 修改push監聽事件,用來啟動腳本文件
// 碼雲是Push Hook, 而git是push
handler.on('Push Hook', function (event) {
console.log('Received a push event for %s to %s',
event.payload.repository.name,
event.payload.ref);
runCommand('sh', ['./deploy.sh'], function( txt ){
console.log(txt);
});
});
// 啟動腳本文件
function runCommand( cmd, args, callback ){
var child = spawn( cmd, args );
var resp = 'Deploy OK';
child.stdout.on('data', function( buffer ){ resp += buffer.toString(); });
child.stdout.on('end', function(){ callback( resp ) });
}
3-4. 構建自動化腳本文件
通過指令vim deploy.sh
構建並寫入腳本文件,腳本執行命令的主要操作流程為
1.進入服務器git倉庫-> 2.pull遠程倉庫上的代碼-> 3.下載新的node包-> 4.編譯新的dist包
ps:
1)develop_qa 是本人用來發布代碼的分支,這個可以替換成你的分支
2)WEB_PATH是服務器代碼倉庫的路徑,按照我們第一步設置的代碼倉庫應該在web文件夾下
3)web文件夾我是創建在根目錄下的,也就是和/opt,/etc同級
4)yourprogram就是你上面clone的項目地址,這里改成你自己的項目就行
WEB_PATH='/web/yourprogram/'
WEB_USER='root'
WEB_USERGROUP='root'
echo "Start deployment"
cd $WEB_PATH
echo "pulling source code..."
git reset --hard origin/develop_qa
git clean -f
git pull
git checkout develop_qa
echo "changing permissions..."
npm install
npm run build
echo "build end"
chown -R $WEB_USER:$WEB_USERGROUP $WEB_PATH
echo "Finished."
3-5. 在遠程倉庫構建webhooks
1.設置webhooks
在碼雲上設置
這個時候我們就需要匹配上面node環境配置的內容
在github上設置
同上,github上也需要在webhooks上配置
3-6. 運行node服務,實現自動化
1. 使用pm2開啟node服務,並檢查是否配置成功
進入git_webhook通過以下指令啟動node服務
pm2 start index.js --watch
通過pm2 list
可以查看我們的node服務已經啟動了
2. 測試webhooks,查看是否自動部署
這里以碼雲上為例,點擊測試之后,可以看到請求結果是true
測試成功后,我們需要實際提交代碼看下
我之前的分支是develop_qa,提交之后可以看到每次push之后,webhooks都會出發一次
3. pm2查看打印日志
我們在.sh腳本,在index.js中打印了很多日志,但是這些日志是看不到的,這個時候可以通過以下指令看到我們的程序執行情況
方法一:
pm2 monit appid
ps: appid就是下圖的這個id
然后會出現這樣一個界面
當我們提交代碼之后,日志就全打印出來了
方法二:
pm2 logs appid
效果同上
4.待優化點
4-1. 查看npm run build的實時日志
如題,如何在linux服務器上實施查看編譯日志,上面的方法只能是編譯結束后,把日志打印出來,並不能實施看到編譯情況,中間等待的時間就比較懵b了,哪位有什么方法可以實時查看
5. 參考資料:
使用 GitHub Webhook 實現靜態網站自動化部署
都9012年了,你還在手動部署代碼嗎
Github Webhook自動發布代碼
使用 GitHub / GitLab 的 Webhooks 進行網站自動化部署
webhook實現github代碼自動部署
使用Github的webhooks進行網站自動化部署