Node.Js開源:ideploy-讓部署不再頭疼
iDeploy
-
1.簡介
-
2.項目技術棧
-
3.快速啟動
-
4.部署第一個項目
-
5.多語言支持
-
6.編寫插件支持高級功能
簡介
ideploy是為前端團隊構建部署工程化而開發的一個持續交付平臺.我們根據團隊人員,項目增長而面臨的越來越多在構建,交付等日常工作中的痛點,設計了很多特有而簡單易用的功能,節省了團隊很多構建部署的協調和copy體力工作,極大的提升了團隊的開發效率。隨著功能的完善,覺得這個系統可以幫助很多類似我們這樣成長中的前端團隊(當然系統其實也是支持java,php等項目的部署的,通過插件編寫也可以支持go甚至更多語言的構建部署)實現快速構建,快速部署,放心上線。
技術棧
-
開發語言: nodejs
-
數據庫: mysql
-
后端框架: thinkjs
-
前端js框架 react
-
前端ui框架 ant.design
快速啟動(只支持linux)
-
git clone xxxxx.git 代碼到本地
-
安裝nodejs 依賴:在根目錄下運行npm install
-
安裝ansible (依賴ansible做部署前后的命令行執行)
-
安裝mysql 數據庫,這里就不展開講了,具體請參考: mysql文檔
-
新建一個數據庫(名字自己取一個就行,比如fe_build),并且開放足夠的訪問權限,具體可以參考 mysql文檔
-
配置數據庫:
打開src/common/config/db.js,分別填寫數據庫ip地址,數據庫名稱,用戶名和密碼,如下所示
export default { type: 'mysql', log_sql: true, log_connect: true, adapter: { mysql: { host: '127.0.0.1', port: '', database: 'wdfe_publish', user: 'root', password: '', prefix: '', encoding: 'utf8' }, } } -
代碼,通知郵件等訪問權限配置:
由于構建部署系統需要從代碼倉庫(svn,git)拉取代碼,所以需要首先配置svn倉庫用戶名和密碼
打開src/common/config/config.js,分別填寫各項配置,具體如下:
export default { cvsUser: 'myuser',//svn用戶名 cvsPass: 'mypass',//svn密碼 emailHost: 'smtp.qq.com',//通知郵箱地址,這里用qq郵箱作為參考 emailport: 465,//端口 emailUser: '3333@qq.com',//郵箱賬號 emailPass: 'xxxxx',//郵箱授權碼(具體可以登錄mail.qq.com->設置->賬戶->POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服務->生成授權碼獲取) cvsDir: '/temp',//svn代碼臨時保存目錄 port: 80 //服務器端口,就是部署平臺的web服務端口, }如果是git項目請保證部署機器能直接有訪問git的權限
-
代碼編譯,啟動
輸入命令以下命令進行編譯:
npm run build編譯完成,運行以下名命令啟動:
npm run start也可以用forever或者pm2來管理服務,以forever為例:
npm install -g forever項目內置了forever的啟動和停止腳本:
./start.sh ./stop.sh服務器起來以后,我們直接訪問
頁面自動跳到登錄注冊頁面,說明啟動成功:

-
導入數據庫腳本,生成數據庫基礎表結構 這一步主要是為系統運行創建需要的數據庫表,為了方便大家使用,項目提供了一個web程序來建立表結構,直接輸入:
會出現如下界面,點擊‘確定導入數據庫表’生成數據庫。

當然,也可以通過mysql 直接倒入數據庫表結構文件,數據庫表文件是db/db.sql
構建部署第一個項目
-
注冊系統用戶 第一次進入系統會直接跳到登錄頁,如果沒有注冊過則點擊底部注冊鏈接進行填寫用戶名密碼進行注冊,如果注冊過則登錄即可
-
填寫項目信息 登錄進入主界面,我們點擊左邊菜單的新建工程填寫工程基本信息,如下所示:
分別填寫項目名稱,代碼倉庫類型,項目語言,代碼倉庫地址,后面的構建hook,部署hook,hook參數可以先不填(這部分會在高級功能里面詳細描述)
-
填寫部署目標機器,填寫完項目信息,點擊左邊工程列表菜單進入,工程列表頁,點擊剛才新建的項目進入項目主頁:

點擊機器列表頁進入機器列,點擊右上角新建機器,進入新建機器頁面,頁面如下:

機器名稱:隨便取一個機器名稱就可以,比如test1
環境類型:分為測試,預發布,正式,直接選擇就好。
構建項目任務:構建時候執行的命令,比如 npm run build test1,這個是在項目跟目錄下執行(部署這臺機器的時候的構建命令,也可以在部署的時候選用自定義構建命令)
機器ip:填寫目標部署機器,就是本項目要部署的機器ip
發布源目錄:需要部署的目錄,即執行構建完構建后需要部署到目標機器的目錄,多個可以用';'隔開,對應發布目標目錄項數據
發布目標目錄:需要將‘發布源目錄’里的目錄部署到目標機器的對應目錄,多個用';'隔開,對應發布目標項。
部署hook:(自定義hook,具體會在高級使用里有描述)
hook參數:(自定義hook參數,具體會在高級使用里有描述)
部署命令執行目錄:如果部署時需要在目標機器執行命令,則需要填寫命令執行目錄
部署前執行命令:如果部署前需要在目標機器執行命令,則需要填寫命令,該命令會在開始部署之前在目標機器的‘部署命令執行目錄’上執行
部署完成執行命令:如果部署后需要在目標機器執行命令,則需要填寫命令,該命令會在完成部署之后在目標機器的‘部署命令執行目錄’上執行
ssh用戶:最終的部署是用rsync命令部署的,需要填寫ssh用戶名
ssh密碼:如果需要ssh密碼則填寫上
-
構建部署
填寫完機器就可以進行部署了,點擊工程列表菜單進入工程列表頁,點擊項目進入項目主頁。 首先點擊‘開始檢出’將代碼從代碼倉庫拉取到部署平臺機器,這里部署平臺做了幾件事情: 1.將本次要部署代碼從代碼倉庫部署到部署機器 2.判斷是否有過上線部署如果有則,則拉取上次部署代碼tag,進行比較,列出本次部署跟上次線上部署的新增文件,修改文件未修改文件,并根據提交人顯示從上次上線正式環境到本次部署的提交歷史,如下圖所示:

黃色用戶名按鈕顯示的是從上次部署上線到現在,都有誰提交了多少次commit(按鈕內容是提交者id,右上角數字是提交次數),點擊按鈕彈出該成員從上次上線到本次上線間的提交歷史,如下圖所示:

點擊某個文件右邊的藍色‘查看’按鈕,會顯示出該文件在本次提交的具體修改(綠色表示提交后版本,紅色表示提交前版本),如下圖所示:

除了列出每個成員的commit歷史,并提供查看每次修改的記錄以外,系統還提供了從上次正式上線到本次上線間文件的變化總覽和明細,提供了新增,修改,未修改3個tab來顯示文件變化情況(tab右上角的數字表示新增,修改,未修改的數字)。底部的文件列表列出了具體文件,對于修改的文件,點擊‘查看差異’按鈕可以顯示具體修改了文件的那些地方,如下圖所示:

檢查檢出步驟的各種輸出,都沒問題后就可以進行構建打包了。由于部署系統支持部分文件上線的功能。如果需要部分文件上線,需要從檢查結果列表里面點擊選擇要上線的文件,并選擇是通過只上線選擇文件還是上線除被選擇文件以外的文件的方式來實現部署上線,如下圖所示:

到這里我們可以開始對項目進行構建打包了,你可以通過選擇指定機器部署構建來執行構建(執行在填寫部署機器時填寫的構建命令進行構建),也可以通過自定義構建命令來進行構建(填寫的命令會在跟目錄下直接執行),如果是js項目,為了減少npm install的時間,第一次請選擇是否跟新node_modules,后面如果構建依賴沒有變化,則可以不選擇,界面如下圖:

點擊‘構建’按鈕執行構建,構建命令輸出可以在‘后臺日志’里看到,查看輸出日志,看看是否構建成功,如下圖所示:

構建完成,還可以通過構建結果的按鈕查看構建后的,如下2圖所示: 

構建完成后,底部的部署按鈕會由灰轉量,這時候我們只要填寫好部署說明和部署原因,點擊部署就可以完成部署了(值得一提的是,可以選擇一次部署多臺機器),如下圖所示:

部署完成后,會彈出一個層,表示部署完成并且詢問是否鎖定部署機器,如果鎖定則這個項目的這臺機器不能再部署,只有本次部署的人解鎖以后才可以繼續部署:

另外從后臺日志輸出模塊也可以實時看到部署過程,如果部署的事正式線上項目,那么系統還會自動給項目打tag留存
到此我們的第一個項目部署完成,需要部署其他項目或者機器的,請按照添加項目的機器的規則進行添加部署即可</code></pre>
支持多語言構建部署:
這個項目本來是為了前端構建部署而設計的,但是隨著系統的日益完善,我們也支持其他語言如 java項目的構建和部署,接下來我們來看看如何部署一個通過maven管理的javaweb項目(我隨便找了個javaweb項目fork出來: https://github.com/luyongfugx/maventest.git)。
1.首先部署平臺所在機器需要安裝jdk(java運行環境),目標機器安裝好tomcat
2.在新建項目的時候,我們選擇程序語言為java(這樣在點擊構建的時候,其實是執行,src/common/service/impl/build_java.sh '命令執行目錄' 'mvn package 命令行' '項目id' '是否npm install')
3.在添加機器時,構建命令我們填寫mvn package(maven編譯命令),部署前需要刪除服務器上代碼可以直接配置部署前命名刪除,部署后需要重啟則可以填寫重啟命令比如這個項目我們填寫的如下信息:


以上是我們內置java語言的內置腳本。如果想添加其他語言的部署,也可以通過擴展程序來支持,舉個增加go語言的例子 首先打開frontend/component/project_detail_component/do_build.jsx文件,增加新建項目的時候的go語言的支持,代碼如下
this.state={
getItemList:'',
selectedRows:'',
codeLangArray:['javascript','java','go'],//增加go語言支持。
selectedMacRowKeys :''
}
添加完重新build項目運行,添加項目的時候語言就多了一個go選項,填上你的項目名稱和代碼倉庫地址(這個例子是一個特別簡單的httpserver,需要本地編譯上傳,重啟)。 然后到src/common/service/ipml目錄下增加build_go.sh文件,點擊構建的時候會執行這個文件,并傳入4個參數,'命令執行目錄' '執行的命令' '項目id' '是否npm install',根據這個我們可以執行編譯命令,以下是我們寫的build_go.sh文件。
#!/bin/bash
projectPath=$1
cd $projectPath
echo '開始構建'
$2
接著我們需要在添加機器的時候填寫構建命令和重啟命令,例子如下:


添加完我們就可以走之前的構建部署流程進行部署了,部署完成輸入: http://localhost:4000/string 看到內容說明部署成功
編寫插件支持高級功能
部署系統還提供了2種hook,方便我們在構建,部署前后編程做一些特殊的工作(比如我們部署一個web服務的過程中,如果部署時間比較長,為了避免用戶訪問到正在部署的機器,需要先從nginx中摘掉,等部署完后再把他添加到nginx列表中),在這我們舉個例子來做一個示范。 1.首先我們需要知道如何調試部署平臺程序 部署平臺主要包含2部分代碼: web前端代碼,主要由reactjs+antd組成,根目錄下執行npm run frontdev來自動監控編譯前端代碼 web后端代碼,用thinkjs框架開發,根目錄下執行npm run dev來自動監控編譯后端代碼
2.hook分為構建hook和部署hook兩種。 構建hook,顧名思義就是構建某個項目的時候調用的hook,分為構建前調用和構建后調用2個hook方法。由于項目使用thinkjs開發,我們把hook類定義成一個thinkjs service類,具體的一個例子,我們新建一個名字為build_nodejs_plugin.js的文件,內容為:
'use strict';
class BuildPlugin extends think.service.base {
init(...args) {
super.init(...args);
}
async before(params){
console.log('before build hook :',params);
return params;
}
async after(params){
console.log('afterProject build hook :',params);
return params;
}
}
export default new BuildPlugin();
before方法是項目構建前會調用,after方法是項目構建后會調用,params為傳入參數,參數主要是一些項目信息和構建信息,比如:
{
id: 17,
name: 'ssr',
creater: 'waynelu',
vcs_type: 1,
code_url: 'https://github.com/luyongfugx/vue-ssr-hmr-template.git',
build_type: 0,
online_tag: '2017022700004',
last_tag: '2017022700004',
pub_time: '2017-02-24 10:14:30',
status: '1',
op_item_id: 0,
op_item_name: '0',
code_lang: 'javascript',
hook_params: 'port:8081',
deploy_hook: 'deploy_nodejs_plugin',
build_hook: 'build_nodejs_plugin',
task: 'build ',
pro_id: 17,
pro_name: 'ssr',
sessionUser: { id: 1, name: 'luyongfu', pass: '111111', avatar: 'avatar' },
shellParams:
{ build_shell: './src/common/service/impl/build_javascript.sh',
buildDir: './temp/luyongfu/17',
task: 'build ',
isNpmInstall: '1' },
buildDir: './temp/luyongfu/17' }
將這個js放到src/common/service目錄下,然后到項目信息里面添加構建hook為build_nodejs_plugin,這樣在構建前后會分別調用before和after,如果想添加參數, 可以填寫hook參數,這個參數會被傳入before,after方法里。
部署hook,是在部署前后調用的hook,內部又細分為部署項目前后的總hook和部署某臺機器前后的hook,我們還是同樣建立一個deployHook,新建一個deploy_nodejs1_plugin.js文件,內容如下:
'use strict';
class DeployPlugin1 extends think.service.base {
init(...args) {
super.init(...args);
}
async beforeProject(params){
console.log('beforeProject hook1 :',params);
return params;
}
async afterProject(params){
console.log('afterProject hook1 :',params);
return params;
}
async beforeMachine(params,projectHookParams){
console.log('beforeMachine hook1 :',params,projectHookParams);
return params;
}
async afterMachine(params,projectHookParams){
console.log('afterMachine hook1 :',params,projectHookParams);
return params;
}
}
export default new DeployPlugin1();
我們同樣把這個文件放到src/common/service目錄下,這樣在部署的時候,一開時會調用beforeProject,然后再每臺機器部署前后調用beforeMachine,afterMachine方法,最后再調用afterMachine 方法,我們在項目基本信息的時候填寫部署hook為deploy_nodejs1_plugin,如果需要每臺機器有特殊hook,則在機器基本信息里填寫部署hook(這時候部署這臺機器時會只執行本hook的beforeMachine,afterMachine方法,不執行項目基本信息里面的beforeMachine,afterMachine方法)
項目主頁:http://www.baiduhome.net/lib/view/home/1493171216247