GITLAB--webhooks自动化部署更新


time 2020-05-15

author Venki

theme 本篇博文主要目的是:将自己部署的gitlab代码管理系统,实现本地提交和服务器自动更新,希望可以帮助到和我一样有需求的小伙伴们。

statement 本篇博文在借鉴他人文章的基础之上进行重新修改,虽然其中磕磕绊绊遇到许多问题,但好在一一都解决了,感谢这篇文章说说配置gitlab的webhook时踩过的坑


有话先说
  1. 关于gitlab

之前已经部署gitlab,并且可以正常使用,之前我的博文有写到关于本地部署gitlab的详细文章,有意者请查看Linux-安装-Gitlab

  1. 关于git

Linux服务器已经安装了git工具,git的安装,再简单不过,请自行百度!

  1. 关于环境

我用的是centOs nginx 以及php环境实现的,但是钩子这东西,其实就是一个接口,所以,不管什么语言,其实原理都是一样的。

  1. 关于PHP和nginx的安装我的博客也有文章写过,请自行查阅Linux-安装-PHPLinux-安装-Nginx
正文开始
1. 业务场景
  • 为了方便管理,用公司一台服务器自行搭建了gitlab用来管理代码,Windows上面开发,然后提交到gitlab之后,服务器代码自动更新。
2. 逻辑介绍
  • 提交(git push)时刻,触发钩子,钩子执行相应程序,拉取分支代码,实现自动更新
3. 编写钩子
  • 其实就相当于一个接口地址,只要gitlab可以调通就行
  • 配置一个nginx站点,并且可访问即可
server {
        listen       5698; # 端口
        server_name  192.168.1.xxx; # IP地址
        root   /home/app/hooks; # 钩子脚本所在目录
        location / {
                index  index.html index.htm index.php;
                try_files $uri $uri/ /index.php?$query_string;
                autoindex  on;
        }
        # 关闭 [/favicon.ico] 和 [/robots.txt] 的访问日志。
        # 并且即使它们不存在,也不写入错误日志。
        location = /favicon.ico { access_log off; log_not_found off; }
        location = /robots.txt  { access_log off; log_not_found off; }

        # 将 [404] 错误交给 [/index.php] 处理,表示由 Laravel 渲染美观的错误页面。
        error_page 404 /index.php;

        # URI 符合正则表达式 [\.php$] 的请求将进入此段配置
        location ~ \.php$ {
            # 配置 FastCGI 服务地址,可以为 IP:端口,也可以为 Unix socket。
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /$document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
        # 通俗地说,以上配置将所有 URI 以 .php 结尾的请求,全部交给 PHP-FPM 处理。

        # 除符合正则表达式 [/\.(?!well-known).*] 之外的 URI,全部拒绝访问
        # 也就是说,拒绝公开以 [.] 开头的目录,[.well-known] 除外
        location ~ /\.(?!well-known).* {
            deny all;
        }
}
  • 我在/home/app/hooks/下面写了一个脚本webhook.php,只要通过上述nginx代理可以成功解析,那么第一步就完成
<?php
echo '测试钩子接口是否调通';
  • 总之一句话:首先你要编写一个接口文件,先不要管里面的代码是什么,只要可以调通就好!
4. gitlab添加钩子
  • 每个项目都要配一个webhooks,因为每个项目可能控制的逻辑不一样以及分支代码不一样,所以为了后续可控,就需要每个仓库都要配置webhooks
  • 配置页面如下

配置钩子01

配置钩子02

配置钩子03

5. 编写钩子脚本业务代码

hook.php(主要是git push 触发后进行操作)

<?php
error_reporting(E_ALL);
 
// 根据token获取项目信息
function getProjectInfoByToken($token, $project_map)
{
    $return = [];
    foreach ($project_map as $map) {
        if ($map['access_token'] == $token) {
            $return = $map;
            break;
        }
    }
 
    return $return;
}
include_once './config.php'; 
// 这里填你的gitlab服务器ip
$valid_ip = array('192.168.1.xxx','192.168.1.xxx'); 
// 这是gitlab服务器上配置的access_token
$client_token = $_SERVER['HTTP_X_GITLAB_TOKEN'];    
$client_ip = $_SERVER['REMOTE_ADDR'];
// 按照日期生成日志文件
$file_name = date('Y-m-d').'_'.'webhook.log';
$data = ['time' => date('Y-m-d H:i:s'), 'client_ip' => $client_ip];
$data = array_merge($data, $_POST, $_GET, $_SERVER);
$project = getProjectInfoByToken($client_token, $project_map);

if (empty($project)) {
    $data['result'] = 'Token mismatch!';
    $log_data = json_encode($data) . PHP_EOL . PHP_EOL;
    var_dump(file_put_contents($file_name, $log_data, FILE_APPEND));
    die('Token mismatch!');
}

if (!in_array($client_ip, $valid_ip)) {
    $data['result'] = 'Ip mismatch!';
    $log_data = json_encode($data) . PHP_EOL . PHP_EOL;
    var_dump(file_put_contents($file_name, $log_data, FILE_APPEND));
    die('Ip mismatch!');
}

$root = $project['root'];
$command = "cd " . $root . "; git pull origin develop 2>&1"; # 我更新的是develop分支代码
$data['command'] = $command;
// 执行shell命令,需要服务器启用exec函数,默认是关闭的
exec($command, $output);  
// var_dump($output); //这样可以用浏览器调试输出
$data['result'] = $output;
$log_data = json_encode($data) . PHP_EOL . PHP_EOL;
var_dump(file_put_contents($file_name, $log_data, FILE_APPEND));

config.php(此文件是用来控制不同仓库的配置项,这样只需要一个hook.php脚本,就可以管理起来多个仓库,切记,每个仓库的秘钥不一样,否则如果一样,那么只会更新先读取到的第一个正确秘钥仓库)

<?php
return $project_map = [
	'dev' => [
		'name' => 'dev', # 别名
		'access_token' => 'xxx-dev', # 配置钩子时需要的一个秘钥,当然也可以不设置
		'root' => '/home/app/dev' # 仓库所在路径
	],
	'test' => [
		'name' => 'test',
		'access_token' => 'xxx-test',
		'root' => '/home/app/test'
	],
];

5. gitlab上面完善钩子信息
  • 配置钩子04
  • 再次测试,是否可以走通(接下来会遇到一些列坑,现在给予相应的解决方法)

坑系列

  1. 不允许本地发起请求
Url is blocked: Requests to localhost are not allowed
解决方法

问题1

  1. .git无权限
error: cannot open .git/FETCH_HEAD: Permission denied
问题原因

由于脚本是PHP,在执行时是通过php-fpm的,而git的用户是root,所以要查看php-fpm的用户是谁。

找到php-fpm.conf文件或者相应的配置文件

php-fpm01
php-fpm02

解决方法
# 更改.git用户和用户组为php-fpm即可
chown -R nginx:nginx .git
# 这里要说一下:.git是要更新仓库所在的位置,也就是每一个仓库都需要执行这个操作
  1. 没有权限写入日志
# 以下只是没有权限错误的一种表现而已
error: unable to create file poetchao.txt (Permission denied)"
解决方法
chmod -R 777 仓库所在路径
  1. git pull 无权限

可能会出现下列问题:

Host key verification failed

fatal: Could not read from remote repository

Please make sure you have the correct access rights

and the repository exists
解决方法
  • 清空/root/.ssh/known_hosts文件内容,然后进入到仓库,进行git pull 按照提示输入yes即可,此问题便解决!

出现下面这个问题:

"Permission denied, please try again.",
"Permission denied, please try again.",
"Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).",
"fatal: Could not read from remote repository.",
"Please make sure you have the correct access rights",
"and the repository exists."
问题原因

gitlab用户是root,但是执行php-fpm的用户是nginx,没有权限拉取

解决方法
  • 一定要晓得php-fpm的用户是谁,因为钩子文件是PHP文件,git执行钩子文件中的函数时(git pull)
  • 知道哪个用户去Git pull 之后,就要将这个用户下面生成的id_rsa.pub加入到gitlab的ssh-key列表中,然后就可以了
# 进入nginx(也就是php-fpm用户)家目录
cd /home/nginx/.ssh
# 生成ssh-key 一路回车
ssh-keygen -t rsa -f nginx -C 'nginx key'
# 执行上述命令生成两个文件,然后id_rsa  id_rsa.pub,将id_rsa.pub内容添加到gitlab中的ssh-key处

添加ssh-key

至此,配置完成,如有疑惑,请留言,我将耐心解决!谢谢!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈文小超_自律

努力自己,幸福他人

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值