根據(jù)業(yè)務(wù)需求嫉沽,已部署GitLab-CE辟犀,網(wǎng)站代碼上線流程如下圖:
開發(fā)者 push 推送代碼之后,網(wǎng)站代碼仍沒(méi)更新绸硕,還需要操作多一步:登錄前端web服務(wù)器堂竟,手動(dòng)git pull 拉取更新的代碼魂毁。這一步是運(yùn)維的工作,很無(wú)趣又煩瑣出嘹。
幸虧席楚,GitLab提供了Webhooks功能,可以輕松實(shí)現(xiàn)網(wǎng)站代碼自動(dòng)更新部署税稼。
一烦秩、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.
簡(jiǎn)單說(shuō)明
webhooks允許指定一個(gè)URL,用于觸發(fā)push或其他事件時(shí)進(jìn)行自定義操作郎仆。
例如只祠,當(dāng)開發(fā)者push代碼到GitLab服務(wù)器,會(huì)觸發(fā)push事件扰肌,GitLab會(huì)發(fā)送一個(gè)POST請(qǐng)求連帶數(shù)據(jù)(數(shù)據(jù)格式)給webhooks指定的URL抛寝,該URL可以是前端web的php程序或Python程序等。這樣曙旭,每當(dāng)GitLab有push事件盗舰,就能在前端web服務(wù)器上執(zhí)行一個(gè)腳本程序。
使用webhooks的步驟:
- 在前端web服務(wù)器上安裝Git客戶端夷狰,用于拉取遠(yuǎn)程倉(cāng)庫(kù) git pull
- 創(chuàng)建并添加公鑰岭皂,以便免密碼拉取遠(yuǎn)程倉(cāng)庫(kù)
- 創(chuàng)建腳本程序,并配置webhooks
二沼头、安裝Git客戶端
在前端web服務(wù)器上爷绘,執(zhí)行以下安裝命令
# yum install git
三、創(chuàng)建并添加公鑰
前端web服務(wù)器的 nginx 和 php-fpm 都是以 www 用戶來(lái)運(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
遇到交互,全部回車就好猾昆。
最后會(huì)在/home/www/.ssh 目錄下生成兩個(gè)文件陶因,私鑰文件:id_rsa,公鑰文件:id_rsa.pub
添加公鑰到GitLab后臺(tái)
獲取www用戶的公鑰文件內(nèi)容:
cat /home/www/.ssh/id_rsa.pub
復(fù)制公鑰內(nèi)容垂蜗,添加公鑰楷扬,GitLab后臺(tái)添加公鑰的位置:管理員 > Settings > SSH Keys
修改網(wǎng)站根目錄的權(quán)限
修改網(wǎng)站根目錄( /home/www/test/ ) 的權(quán)限,否則以www用戶git pull 會(huì)報(bào)權(quán)限問(wèn)題贴见。
# chmod 775 /home/www/test/ -R
# chown www.www /home/www/test/ -R
測(cè)試
測(cè)試www用戶基于公鑰是否能從Git服務(wù)器遠(yuǎn)程拉取代碼
手動(dòng)執(zhí)行pull操作
# su www
$ cd /home/www/test/
$ git pull
四烘苹、部署webhooks
編寫webhooks應(yīng)用的PHP程序
在前端web服務(wù)器的網(wǎng)站根目錄(/home/www/test/)下新建一個(gè)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訪問(wèn)這個(gè)文件 這里是gitlab服務(wù)器IP
$access_ip = array('192.168.1.15','14.xxx.xxx.19');
//如果使用www.xxx.com/xxx.php?token=xxxxxxx 的方式來(lái)傳送驗(yàn)證字符串片部,則用這個(gè)方法獲取
# $client_token = $_GET['token'];
// 獲取請(qǐng)求端的secret token
$client_token = $_SERVER["HTTP_X_GITLAB_TOKEN"];
//獲取請(qǐng)求端的IP
$client_ip = $_SERVER['REMOTE_ADDR'];
//把請(qǐng)求的IP和時(shí)間寫進(jìn)log
fwrite($fs, 'Request on ['.date("Y-m-d H:i:s").'] from ['.$client_ip.']'.PHP_EOL);
//驗(yàn)證token 有錯(cuò)就寫進(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);
}
//獲取請(qǐng)求端發(fā)送來(lái)的信息镣衡,具體格式參見gitlab的文檔
$json = file_get_contents('php://input');
$data = json_decode($json, true);
//如果有需要 可以打開下面,把傳送過(guò)來(lái)的信息寫進(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會(huì)禁止這個(gè)函數(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] 按鈕,測(cè)試配置是否生效揩环。
五、遇到的問(wèn)題
在部署webhooks中幅虑,遇到了個(gè)很詭異的問(wèn)題丰滑。
前提說(shuō)明
GitLab-CE 版本:9.2.6
使用xhang項(xiàng)目對(duì)GitLab-CE進(jìn)行漢化過(guò)
問(wèn)題描述:
已成功部署webhooks,按 [Test] 按鈕測(cè)試正常倒庵。
但在實(shí)際使用中褒墨,開發(fā)者push代碼后,webhooks.php沒(méi)有被執(zhí)行擎宝,前端web代碼沒(méi)有g(shù)it pull 記錄郁妈,日志也沒(méi)有記錄。GitLab沒(méi)有檢測(cè)到開發(fā)者的push事件绍申。
問(wèn)題分析:
- 通過(guò)另外部署一套同版本的噩咪、不打漢化補(bǔ)丁的GitLab-CE,發(fā)現(xiàn)不是漢化補(bǔ)丁的問(wèn)題极阅。
- 回想起之前遇到的一個(gè)問(wèn)題胃碾,在GitLab-CE上新創(chuàng)建test項(xiàng)目時(shí),開發(fā)者push后筋搏,GitLab上仍然顯示該項(xiàng)目是空項(xiàng)目仆百,無(wú)法檢測(cè)到push事件,后來(lái)還是通過(guò)修改項(xiàng)目名來(lái)使得其能識(shí)別push事件奔脐。
問(wèn)題解決:
后來(lái)偶然發(fā)現(xiàn)俄周,webhooks時(shí)GitLab沒(méi)有及時(shí)檢測(cè)到開發(fā)者的push事件,是因?yàn)閷?duì) /var/opt/gitlab/ 目錄做了軟鏈接的緣故髓迎。
去掉軟鏈接峦朗,改為正常的目錄路徑。