利用GitLab的Webhooks功能,實(shí)現(xiàn)網(wǎng)站代碼自動更新部署

根據(jù)業(yè)務(wù)需求,已部署GitLab-CE,網(wǎng)站代碼上線流程如下圖:

開發(fā)者 push 推送代碼之后,網(wǎng)站代碼仍沒更新,還需要操作多一步:登錄前端web服務(wù)器,手動git pull 拉取更新的代碼。這一步是運(yùn)維的工作,很無趣又煩瑣。

幸虧,GitLab提供了Webhooks功能,可以輕松實(shí)現(xiàn)網(wǎng)站代碼自動更新部署。

一、webhooks原理

Webhooks的原理

Project webhooks allow you to trigger a URL if for example new code is pushed or a new issue is created.
You can configure webhooks to listen for specific events like pushes, issues or merge requests. GitLab will send a POST request with data to the webhook URL.
Webhooks can be used to update an external issue tracker, trigger CI jobs, update a backup mirror, or even deploy to your production server.

簡單說明

webhooks允許指定一個URL,用于觸發(fā)push或其他事件時進(jìn)行自定義操作。
例如,當(dāng)開發(fā)者push代碼到GitLab服務(wù)器,會觸發(fā)push事件,GitLab會發(fā)送一個POST請求連帶數(shù)據(jù)(數(shù)據(jù)格式)給webhooks指定的URL,該URL可以是前端web的php程序或Python程序等。這樣,每當(dāng)GitLab有push事件,就能在前端web服務(wù)器上執(zhí)行一個腳本程序。

使用webhooks的步驟:

  • 在前端web服務(wù)器上安裝Git客戶端,用于拉取遠(yuǎn)程倉庫 git pull
  • 創(chuàng)建并添加公鑰,以便免密碼拉取遠(yuǎn)程倉庫
  • 創(chuàng)建腳本程序,并配置webhooks

二、安裝Git客戶端

在前端web服務(wù)器上,執(zhí)行以下安裝命令

# yum install git

三、創(chuàng)建并添加公鑰

前端web服務(wù)器的 nginx 和 php-fpm 都是以 www 用戶來運(yùn)行的,所以要為www用戶創(chuàng)建并添加公鑰。

www 用戶的家目錄是: /home/www/

修改 www 用戶的 shell 為 /bin/bash

www:x:511:511::/home/www:/bin/bash

創(chuàng)建用戶的公鑰

# su www
$ ssh-keygen -t rsa

遇到交互,全部回車就好。
最后會在/home/www/.ssh 目錄下生成兩個文件,私鑰文件:id_rsa,公鑰文件:id_rsa.pub

添加公鑰到GitLab后臺

獲取www用戶的公鑰文件內(nèi)容:

cat /home/www/.ssh/id_rsa.pub

復(fù)制公鑰內(nèi)容,添加公鑰,GitLab后臺添加公鑰的位置:管理員 > Settings > SSH Keys

修改網(wǎng)站根目錄的權(quán)限

修改網(wǎng)站根目錄( /home/www/test/ ) 的權(quán)限,否則以www用戶git pull 會報權(quán)限問題。

# chmod 775 /home/www/test/ -R
# chown www.www /home/www/test/ -R

測試

測試www用戶基于公鑰是否能從Git服務(wù)器遠(yuǎn)程拉取代碼

手動執(zhí)行pull操作

# su www
$ cd /home/www/test/  
$ git pull

四、部署webhooks

編寫webhooks應(yīng)用的PHP程序

在前端web服務(wù)器的網(wǎng)站根目錄(/home/www/test/)下新建一個webhooks.php

<?php
//網(wǎng)站目錄
$www_file='/home/www/test/';

//打開網(wǎng)站目錄下的hooks.log文件,需要在服務(wù)器上創(chuàng)建,并給寫權(quán)限
$fs = fopen('/home/www/test/hooks.log', 'a');

fwrite($fs, '================ Update Start ==============='.PHP_EOL.PHP_EOL);

//自定義字串掩碼 用于驗(yàn)證
$access_token = 'QhNO8YHqym5PHQQsexapF7041xOhzm62DRH';

//接受的ip數(shù)組,也就是允許哪些IP訪問這個文件 這里是gitlab服務(wù)器IP
$access_ip = array('192.168.1.15','14.xxx.xxx.19');

//如果使用www.xxx.com/xxx.php?token=xxxxxxx 的方式來傳送驗(yàn)證字符串,則用這個方法獲取
# $client_token = $_GET['token'];

// 獲取請求端的secret token
$client_token = $_SERVER["HTTP_X_GITLAB_TOKEN"];

//獲取請求端的IP
$client_ip = $_SERVER['REMOTE_ADDR'];

//把請求的IP和時間寫進(jìn)log
fwrite($fs, 'Request on ['.date("Y-m-d H:i:s").'] from ['.$client_ip.']'.PHP_EOL);

//驗(yàn)證token 有錯就寫進(jìn)日志并退出
if ($client_token !== $access_token)
{
    echo "error 403";
    fwrite($fs, "Invalid token [{$client_token}]".PHP_EOL);
    exit(0);
}

//驗(yàn)證ip
if ( !in_array($client_ip, $access_ip))
{
    echo "error 503";
    fwrite($fs, "Invalid ip [{$client_ip}]".PHP_EOL);
    exit(0);
}

//獲取請求端發(fā)送來的信息,具體格式參見gitlab的文檔
$json = file_get_contents('php://input');
$data = json_decode($json, true);

//如果有需要 可以打開下面,把傳送過來的信息寫進(jìn)log
# fwrite($fs, 'Data: '.print_r($data, true).PHP_EOL);

//執(zhí)行shell命令并把返回信息寫進(jìn)日志
$output=shell_exec("cd $www_file && git pull 2>&1");
fwrite($fs, 'Info:'. $output.PHP_EOL);

fwrite($fs,PHP_EOL. '================ Update End ==============='.PHP_EOL.PHP_EOL);

$fs and fclose($fs);

?>

修改PHP配置

因?yàn)閣ebhooks用到的php代碼中使用了 shell_exec 函數(shù),一般配置php會禁止這個函數(shù),需要打開 shell_exec 函數(shù)。
修改前端web服務(wù)器上php.ini的 disable_functions 列表,去掉 shell_exec 。
重啟php-fpm服務(wù)。

配置GitLab

project > Settings > Integrations

Secret Token中字符串的值,要跟webhooks.php中$access_token 的值相同。
Enable SSL verification 不要勾。

可以按 [Test] 按鈕,測試配置是否生效。

五、遇到的問題

在部署webhooks中,遇到了個很詭異的問題。

前提說明

GitLab-CE 版本:9.2.6
使用xhang項(xiàng)目對GitLab-CE進(jìn)行漢化過

問題描述:

已成功部署webhooks,按 [Test] 按鈕測試正常。
但在實(shí)際使用中,開發(fā)者push代碼后,webhooks.php沒有被執(zhí)行,前端web代碼沒有g(shù)it pull 記錄,日志也沒有記錄。GitLab沒有檢測到開發(fā)者的push事件。

問題分析:

  • 通過另外部署一套同版本的、不打漢化補(bǔ)丁的GitLab-CE,發(fā)現(xiàn)不是漢化補(bǔ)丁的問題。
  • 回想起之前遇到的一個問題,在GitLab-CE上新創(chuàng)建test項(xiàng)目時,開發(fā)者push后,GitLab上仍然顯示該項(xiàng)目是空項(xiàng)目,無法檢測到push事件,后來還是通過修改項(xiàng)目名來使得其能識別push事件。

問題解決:

后來偶然發(fā)現(xiàn),webhooks時GitLab沒有及時檢測到開發(fā)者的push事件,是因?yàn)閷?/var/opt/gitlab/ 目錄做了軟鏈接的緣故。
去掉軟鏈接,改為正常的目錄路徑。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 動機(jī) 前段時間st0rm23在自己的服務(wù)器上搭好了自己的gitlab,現(xiàn)在我準(zhǔn)備開搞自己的web項(xiàng)目了。但是如果每...
    st0rm23閱讀 47,448評論 13 25
  • GIT分布式版本控制系統(tǒng)最佳實(shí)踐 這篇文章來自于老男孩教育高級架構(gòu)師班12期的徐亮偉同學(xué)。 首先感謝老男孩架構(gòu)師班...
    meng_philip123閱讀 3,507評論 4 36
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,969評論 19 139
  • 小炎最近身體出了點(diǎn)問題,經(jīng)常出入醫(yī)院,醫(yī)生告訴她這是過勞所致。 小炎本來想,多加班,賺多一點(diǎn)錢,過年回家給爸媽買些...
    九蹬閱讀 740評論 4 8
  • 假期里,和家人策劃吃吃喝喝,兜兜轉(zhuǎn)轉(zhuǎn),難得放松休閑。幸福的感覺當(dāng)然有,但事情也分兩面。這幾天來我的真切感受是:在兩...
    心蓮Kallen閱讀 475評論 8 7