1. 前置條件
- 有一臺本身的服務器。好比阿里雲,騰訊雲之類
- 有遠程倉庫可以push代碼,pull代碼。好比github,或者碼雲
- 遠程倉庫有webhooks功能
2. 自動化部署流程
3. 構建流程
3-1. 服務器部署git環境
1. 安裝git
經過指令yum install git
安裝git
安裝按完成後能夠看到
html
2. 設置ssh密鑰
經過如下指令建立密鑰,-C後面的內容,寫你的郵箱名字就行node
ssh-keygen -t rsa -C "youreamil@163.com"
不須要密碼的話,一直回車就好了,而後能夠獲得兩個文件:id_rsa和id_rsa.publinux
3. 添加ssh密鑰
在github添加密鑰
在碼雲添加密鑰
git
4. 測試密鑰添加成功
github經過如下指令測試github
ssh -T git@github.com
碼雲經過如下指令測試web
ssh -T git@gitee.com
碼雲測試經過會顯示 success,以下圖所示npm
5. clone遠程代碼倉庫到服務器
接着找到遠程倉庫代碼的ssh地址
這個時候須要創建一個文件夾mkdir web
,而後進入web文件夾中,經過git clone
指令把遠程倉庫拷貝到服務器的web目錄下
json
git clone git@gitee.com:XXXXXX.git
clone結束後,咱們能夠看到服務器裏面已經有了代碼內容vim
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: develop_qa 是本人用來發布代碼的分支,這個能夠替換成你的分支
WEB_PATH是服務器代碼倉庫的路徑,按照咱們第一步設置的代碼倉庫應該在web目錄下
WEB_PATH='/web/XXX/' 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
而後會出現這樣一個界面
當咱們提交代碼以後,日誌就全打印出來了
4. 參考資料:
使用 GitHub Webhook 實現靜態網站自動化部署
都9012年了,你還在手動部署代碼嗎
Github Webhook自動發佈代碼
使用 GitHub / GitLab 的 Webhooks 進行網站自動化部署
webhook實現github代碼自動部署
使用Github的webhooks進行網站自動化部署