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-安装-PHP、Linux-安装-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代理可以成功解析,那么第一步就完成
  • 总之一句话:首先你要编写一个接口文件,先不要管里面的代码是什么,只要可以调通就好!
4. gitlab添加钩子
  • 每个项目都要配一个webhooks,因为每个项目可能控制的逻辑不一样以及分支代码不一样,所以为了后续可控,就需要每个仓库都要配置webhooks
  • 配置页面如下

GITLAB--webhooks自动化部署更新_第1张图片

GITLAB--webhooks自动化部署更新_第2张图片

GITLAB--webhooks自动化部署更新_第3张图片

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

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

 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脚本,就可以管理起来多个仓库,切记,每个仓库的秘钥不一样,否则如果一样,那么只会更新先读取到的第一个正确秘钥仓库)

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

5. gitlab上面完善钩子信息
  • GITLAB--webhooks自动化部署更新_第4张图片
  • 再次测试,是否可以走通(接下来会遇到一些列坑,现在给予相应的解决方法)

坑系列

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

GITLAB--webhooks自动化部署更新_第5张图片

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

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

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

GITLAB--webhooks自动化部署更新_第6张图片
GITLAB--webhooks自动化部署更新_第7张图片

解决方法
# 更改.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处

GITLAB--webhooks自动化部署更新_第8张图片

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

你可能感兴趣的:(项目管理--学习记录)