Skip to content

使用 Git Webhooks 自动化部署

Published: at 07:43 AMSuggest Changes

前一阵子我其实是想用 Google drive + incron 的方式自动提交博客,然而碰到了一些问题,Goole drive 可以同步文件夹,但不能自动同步文件夹,并且没有 git 这样优秀的版本控制。 而我又不想自己手动上传文章以及拉取文章,拉取之后还得手工 hexo g,太麻烦了。 写定时拉取,自动更新的确可以,但是这样太没逼格了。 于是我就查资料,发现了 git 有 webhooks。

什么是 Webhooks

先放几个官方的说明:

简单概括一下(译自 Github Webhooks):

Webhooks 脚本

Webhook 脚本实现可以用 PHP、NodeJS 等,本文仅介绍 PHP 脚本,笔者也用的这个脚本

<?php
// 本地仓库路径
$local = '/var/www/html/';

// 安全验证字符串,为空则不验证
$token = '123456';

// 如果启用验证,并且验证失败,返回错误
$httpToken = isset($_SERVER['HTTP_X_GITLAB_TOKEN']) ? $_SERVER['HTTP_X_GITLAB_TOKEN'] : '';
if ($token && $httpToken != $token) {
    header('HTTP/1.1 403 Permission Denied');
    die('Permission denied.');
}

// 如果仓库目录不存在,返回错误
if (!is_dir($local)) {
    header('HTTP/1.1 500 Internal Server Error');
    die('Local directory is missing');
}

//如果请求体内容为空,返回错误
$payload = file_get_contents('php://input');
if (!$payload) {
    header('HTTP/1.1 400 Bad Request');
    die('HTTP HEADER or POST is missing.');
}

/*
 * 这里有几点需要注意:
 *
 * 1.确保 PHP 正常执行系统命令。写一个 PHP 文件,内容:
 * `<?php shell_exec('ls -la')`
 * 在通过浏览器访问这个文件,能够输出目录结构说明 PHP 可以运行系统命令。
 *
 * 2、PHP 一般使用 www-data 或者 nginx 用户运行,PHP 通过脚本执行系统命令也是用这个用户,
 * 所以必须确保在该用户家目录(一般是/home/www-data 或/home/nginx)下有.ssh 目录和
 * 一些授权文件,以及 git 配置文件,如下:
 * ```
 * + .ssh
 *   - authorized_keys
 *   - config
 *   - id_rsa
 *   - id_rsa.pub
 *   - known_hosts
 * - .gitconfig
 * ```
 *
 * 3.在执行的命令后面加上 2>&1 可以输出详细信息,确定错误位置
 *
 * 4.git 目录权限问题。比如:
 * `fatal: Unable to create '/data/www/html/awaimai/.git/index.lock': Permission denied`
 * 那就是 PHP 用户没有写权限,需要给目录授予权限:
 * ``
 * sudo chown -R :www-data /data/www/html/awaimai`
 * sudo chmod -R g+w /data/www/html/awaimai
 * ```
 *
 * 5.SSH 认证问题。如果是通过 SSH 认证,有可能提示错误:
 * `Could not create directory '/.ssh'.`
 * 或者
 * `Host key verification failed.`
 *
 */
echo shell_exec("cd {$local} && git pull 2>&1");
die("done " . date('Y-m-d H:i:s', time()));

Webhooks 配置

像图片中这样设置就可以了

注意事项

如果不能正常的拉取,你可以先使用下面的 php 程序进行测试。

<?php
$output = shell_exec('ls -lart');
echo "<pre>$output</pre>";
?>

如果网页不能够输出你当前的文件夹下的文件,说明 shell_exe() 函数被禁用了,你需要修改 php.ini,启用该函数

然后用下面的 php 程序接着测试

<?php
// 本地仓库路径
$local = '/var/www/html/';

echo shell_exec("cd {$local} && git pull 2>&1");
die("done " . date('Y-m-d H:i:s', time()));
?>

看看输出的信息。在执行的命令后面加上 2>&1 可以输出详细信息,确定错误位置。

一般情况下有 3 种错误:

对于权限不足,你需要给网站 www 或则 nginx 用户组权限,不是 777 这样的权限,因为 PHP 一般使用 www 或者 nginx 用户运行,PHP 通过脚本执行系统命令也是用这个用户。一般可以用下面的命令解决,具体还是要看你的环境:

sudo chown -R www:www /data/www/
sudo chmod -R g+w /data/www/

对于 ssh 认证错误,你需要保证 www 或则 nginx 用户组的文件夹下有.ssh 目录(一般是/home/www 或/home/nginx)和一些授权文件,以及 git 配置文件,如下:

+ .ssh
 - authorized_keys
 - config
 - id_rsa
 - id_rsa.pub
 - known_hosts
- .gitconfig

而且你需要在 Github、Gitlab、Gitee 中加入你的公钥。具体你可以百度谷歌一下。 输入下面的命令就可以了

ssh-keygen -t rsa

参考资料&转载来源

部分内容是转载自: Github、GitLab、Gitee 使用 Webhooks 实现代码自动部署 其他优秀参考资料: gitlab 利用 webhook 自动部署代码 利用 GitLab 的 Webhooks 功能,实现网站代码自动更新部署 给你的项目增加 Webhooks,自动进行部署(包含 Github/Gitlab) 使用 Gitlab Webhooks 自动部署代码 使用 GitHub / GitLab 的 Webhooks 进行网站自动化部署 git webhooks 实现自动拉取代码 利用 WebHook 实现 PHP 自动部署 Git 代码 使用 Git 的 Webhooks 进行服务器自动部署代码 使用 Github 的 webhooks 进行网站自动化部署


Previous Post
使用 Incron 监控重要文件和文件夹
Next Post
CentOS 7 Google Drive 数据备份与同步