php gitlab 自動更新程式碼的鉤子
做之前查了幾個資料 :
https://segmentfault.com/a/1190000011561808
https://segmentfault.com/a/1190000010698441
本文目的
本文的目的是配置實現在 GitLab 平臺上的程式碼自動部署。想要達到的效果是這樣子的,當客戶端向 GitLab 伺服器的特定分支(如:prod)提交程式碼時,GitLab 伺服器會發送通知給線上程式碼伺服器,程式碼伺服器收到通知之後再拉取 GitLab 伺服器上該分支的最新程式碼。
效果圖如下:
有了 GitLab ,只需要三步就可以實現以上描述的效果了。
步驟一、準備指令碼
在程式碼伺服器端準備好一份處理 GitLab 伺服器通知的指令碼和一份拉取程式碼的指令碼。
GitLab 伺服器所發出來的通知,其實就是向程式碼伺服器發出一個 http 請求,請求中包含了本次提交中的相關資訊,如所提交的分支、誰提交的、本次更新的程式碼等等資訊。
所以在程式碼伺服器中新增一個指令碼,專門處理該請求即可。
可以參考一下 PHP 程式碼: 檔名稱 : gitPull.php
<?php // 處理 GitLab 請求的指令碼 error_reporting(1); $target = '/home/centos/www/xiaoniaoAdmin'; // 生產環境web目錄 $token = 'xiaoniaoAdminPush'; //GitLab 新增的token if (empty($_SERVER['HTTP_X_GITLAB_TOKEN']) || $_SERVER['HTTP_X_GITLAB_TOKEN'] !== $token) { exit('error request'); } $rowData = file_get_contents('php://input', 'r');; $rowData = json_decode($rowData,true); $output = ''; $type = $_GET['type']; // 只拉取 release 分支的程式碼到伺服器 if($rowData['ref'] == 'refs/heads/release'){ if('ims' == $type){ // 觸發拉取程式碼的指令碼 chdir($target); $cmd = "git pull"; shell_exec($cmd); } logg($type." output:".json_encode($output)); } logg($type.':'.$rowData['user_name']." commit to branch:".$rowData['ref']); function logg($data){ $text = '['.date('Y-m-d H:i:s').'] '.$data."\n"; file_put_contents(dirname(dirname(__FILE__)).'/log/gitlab'.date('ymd').'.log',$text,FILE_APPEND); }
這裡的鉤子檔案,可以用 http://www.kobeman.com/gitPull.php 看可以訪問到
這裡的鉤子檔案需要注意以下幾點
php
配置裡需要註釋掉shell_exec
這些被禁用的函式 詳見 shell_exec (https://www.zhihu.com/question/57879484?from=profile_question_card)- 執行命令時切換到管理員使用者最好
- 檢視是否進入你的專案目錄 這裡我是通過
chdir
進入專案目錄 因為cd
命令是沒有用的 詳見 Can't 'cd' with PHP shell_exec() git pull
不能執行 這應該就是許可權的問題 詳見 shell 指令碼中呼叫 git pull 命令無法執行 (https://stackoverflow.com/questions/3173201/sudo-in-php-exec)- 這裡為什麼我們需要獲取這個
$_SERVER
的引數呢 因為GitLab
是通過post
請求這個地址 所以為了驗證之前填入的token
步驟二、配置 webhooks
在專案中配置 webhooks(Web 鉤子) 其實就是在專案中註冊一個觸發器,當專案中的某個事件發生時,該觸發器就會被觸發。在 GitLab 中的觸發器就是一個 http 請求,即一個 http 連結。
如下圖 : 在 gitlab 上的操作截圖
圖中 1 : 可以訪問 鉤子檔案的 url
圖中 2 : 跟 鉤子檔案 中 $token 保持一致,用作請求驗證
步驟三、新增祕鑰
既然是程式碼自動部署,那當然是完全不需要人為參與的啦,這將包括不需要人為輸入密碼。
GitLab 提供了讓每個賬號使用祕鑰登入的功能,配置了賬號祕鑰之後就可以無密碼登入賬號了。程式碼自動部署正是需要這樣子的功能了。
首先要在程式碼伺服器端生成祕鑰:
使用命令
ssh-keygen
,連續按三次回車即可生成一對無密碼保護的祕鑰,它們的名稱分別是id_rsa
和id_rsa.pub
然後將 id_rsa.pub
的內容新增到 GitLab 賬號:
在 GitLab 賬號的 profile setting > SSH keys 貼上並儲存即可
需要注意的地方
通過以上三步,現在已經能夠實現程式碼自動部署了。
如果完成了以上步驟之後,還不能實現程式碼自動部署,最可能出現問題的是賬號的許可權問題了。有兩個地方可能出現許可權的問題。
-
GitLab 賬號的許可權
自動部署所繫結的賬號需要有許可權訪問該專案。
-
程式碼伺服器端執行指令碼的使用者的許可權
首先,該使用者需要有許可權對專案目錄進行讀寫; 然後是,該使用者的祕鑰資訊繫結的是正確的 GitLab 賬號