乾貨:自動部署其實很簡單

應用場景

若是你但願本地執行git push到git服務器後,在目標服務器上直接拉取代碼並進行部署的話,能夠參考下本教程。node

背景

ui同窗平時把素材包都放在git.ui的git倉庫中,幾個版本迭代下來,整個倉庫的大小已經達到了1.7g,每次clone都很艱難...git

直到有一天,有人在羣裏建議能夠直接掛在服務直接訪問...github

對話

思路

拆分這個需求,有兩個點須要實現:web

  1. 在目標機器上部署,能夠訪問到靜態文件。
  2. 在倉庫被push的時候,自動通知目標機器執行步驟1

進一步拆分,從這兩個角度出發,第一個點有不少實現方案,在這裏羅列幾種實現方案:shell

  1. 掛載到目標節點上,使用node設置靜態文件路徑,採用框架生成相應的文件目錄。
  2. 將項目的靜態內容上傳到cdn上,並將全部的靜態內容生成文件索引入口。
  3. 當用戶訪問某個Url時,經過stash API去拉取相關的目錄數據,並生成目錄結構或靜態文件吐給用戶,來實時更新目標文件。

這裏以第一種方案爲例,來具體實現一下。npm

所以整個流程須要分紅三端,客戶端(新變動推送)、git服務器(git掛載服務器)、目標服務器(進行自動部署的服務器)。考慮到第二點,在倉庫被push的時候,要自動觸發消息。天然想到使用githook來處理(githook的介紹能夠看這篇)。可是githook中無論是客戶端鉤子仍是服務端鉤子都只能在客戶端和服務端之間雙向連接,所以須要使用git服務器的webhook功能(webhook介紹)。整個流程以下圖:segmentfault

流程圖

實現

由上面思路流程,node服務須要區分請求的類型:bash

  • GET請求:根據url進行靜態文件重定向
  • POST請求:收到webhook請求,執行腳本,拉取git倉庫

關於靜態文件部署,調研了兩個npm包:stserve-handler。二者均可以進行靜態資源部署,可是經測試,st對中文命名的目錄名支持很差,會出現亂碼,serve-handler對中文目錄支持比較好,故選擇serve-handler。服務器

關於執行腳本拉取倉庫,有兩種方案推薦,一種是node執行腳本或執行命令行命令的方式child_process,利用子進程進行腳本的執行,另一種是第三方的shelljs,是在child_process的基礎上的封裝,調用系統命令更簡單。故選擇第二種。框架

所以具體代碼以下:

var http = require('http');
// 靜態文件部署
var handler = require('serve-handler');
// 執行shell命令
var shell = require('shelljs');

http.createServer(function(request, response) {
  var urlMethod = request.method;
    if(urlMethod === 'POST') {
  		// 拿到POST請求,輸出內容並執行git pull操做
      console.log("POST request");

      var content = "";
      request.on('data', function (chunk) {
        content += chunk;
      });

      request.on('end', function () {
        response.writeHead(200, {"Content-Type": "text/plain"});
        response.write("You've sent: " + content);
        response.end();
        console.log("POST data:",content);
      });
      try{
      	 // 拉取最新代碼
        shell.exec("git pull");
        console.log("POST success");
      }catch(e) {
        console.log("POST fail");
      }
      return;
    }else {
    	// GET請求,直接調用serve-handler來靜態資源重定向
    	console.log("GET request");
    	console.log("GET url", request.url);
    	return handler(request, response, {
 		  "public": "git.ui"
   		});
    }
}).listen(8080);

console.log('Server started');
複製代碼

在目標服務器上用pm2部署服務,同時在git服務器上設置webhook的觸發地址,完成目標服務器的部署。

後續

後續能夠註冊服務和域名,將機器綁定域名,或利用現有服務配置Nginx映射。

你們有興趣的能夠試着實現如下第二種第三種訪問靜態文件的部署方案。

相關文章
相關標籤/搜索