前言
之前使用GitHub Actions可以在提交代码后自动上传到腾讯云COS存储桶,实现静态网站完美自动化部署.那么非静态的网站或者项目需要自动化部署到VPS服务器上就可以使用GitHub Webhooks来实现.作为纯属新手来说,网上查阅了十几篇相关教程,都没法部署成功,最后总算找到了问题关键点,决定整理成文章分享出来,希望能帮助到新手用户.

Webhook支持php,js等多种方式,可以实现简单的部署,也可以实现复杂的自动化构建等功能,本文介绍适合新手用户的php方式,来自动化部署网站.
Webhook简单原理
对于入门新手来说,Webhook可以理解为当你在本地完成代码工作后,Push提交到GitHub,GitHub检测到Push后,使用Webhook发送一条命令到你的VPS服务器上的Webhook.php文件,服务器检测到命令后根据webhook.php中的配置在服务器上执行Pull命令,同步GitHub上的代码到服务器.实现了简单的自动化部署工作.节省了你再次上传至服务器的多余操作.

部署流程
启用shell_exec
编辑php.ini

vi /usr/local/php/etc/php.ini
查找shell_exec,在disable_functions中删除shell_exec字段.

重启php.ini保存设置

/etc/init.d/php-fpm restart
配置站点目录权限
由于Webhook的推送请求是通过http/https方式发送至服务器,根据webhook.php中的命令执行git pull的实为运行php的用户,根据以下命令可以查执行php用户为www.

ps aux | grep php
确保仓库所在的站点目录所有者为www

chown -R www:www /home/wwwroot
切换为www账户
以root账户登陆服务器,修改www的登录权限.

vi /etc/passwd
找到

www❌1003:1003::/home/www:/sbin/nologin
修为改

www❌1003:1003::/home/www:/bin/bash
为www创建ssh公钥
切换为www登陆

su www
创建ssh公钥

ssh-keygen -t rsa

获取你的公钥id_rsa.pub

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

登陆GitHub配置ssh公钥
登陆GitHub - 进入仓库 - Settings - Deploy keys - Add Deploy keys
粘贴刚才创建的公钥

首次git clone仓库
验证ssh公钥配置成功

ssh -T git@github.com

首次clone仓库成功

git clone git@github.com:xxxxxx/xxxxxxx.git

配置webhook.php
在项目网站根目录创建webhook.php获得外网链接为https://yourdoamin.com/webhook.php
粘贴以下代码,只需要更改keySecret和wwwRoot即可.

$value) { 'HTTP_' == substr($key, 0, 5) && $headers[str_replace('_', '-', substr($key, 5))] = $value; if (empty($gitType) && strpos($key, 'GITEE') !== false) { $gitType = 'GITEE'; } if (empty($gitType) && strpos($key, 'GITHUB') !== false) { $gitType = 'GITHUB'; } } if ($gitType == 'GITEE') { if (!isset($headers['X-GITEE-TOKEN']) || $headers['X-GITEE-TOKEN'] != $keySecret) { die('GITEE - 请求失败,秘钥有误'); } } elseif ($gitType == 'GITHUB') { $json_content = file_get_contents('php://input'); $signature = "sha1=" . hash_hmac('sha1', $json_content, $keySecret); if ($signature != $headers['X-HUB-SIGNATURE']) { die('GITHUB - 请求失败,秘钥有误'); } } else { die('请求错误,未知git类型'); } } !is_array($wwwRoot) && $wwwRoot = [$wwwRoot]; foreach ($wwwRoot as $vo) { $shell = sprintf("cd %s && git pull 2>&1", $vo); $output = shell_exec($shell); $log = sprintf("[%s] %s \n", date('Y-m-d H:i:s', time()) . ' - ' . $vo, $output); echo $log; file_put_contents($logFile, $log, FILE_APPEND); } GitHub Webhooks配置 登陆GitHub - 进入仓库 - Settings - Webhooks - Add webhook Payload URL 输入刚才获取的webhook.php的外网链接. Content type 保持默认 Secret 输入刚才配置webhook.php创建的验证密码 Add webhook 完成创建 ![](https://book.baidv.win/post-images/1583652656005.jpg) 恢复关闭www登陆 exit退出www登陆切回root,在次关闭www登陆. vi /etc/passwd 恢复为 www:x:1003:1003::/home/www:/sbin/nologin 自动化部署成功 本地push代码到GitHub后,可以看到返回信息提示服务器pull成功. ![](https://book.baidv.win/post-images/1583652683115.jpg) 关键点和相关错误 权限 网上很多教程都没有提到权限问题,所以对于新手小白来说,就会不知道为什么不成功.而少数提到权限的教程,也没有非常详细指导用户如何配置.所以如果部署有问题,请检查权限问题,新手用户可以严格按照本教程先部署成功,在来自行修改你需要的配置. webhook.php webhook.php的代码网上也有很多种,有些能用有些无法使用,本文提供的是经过测试可用的,大家也可以自行搜索或者编辑. Service Timeout 当遇到push大量代码时,服务器pull需要更长的时间,所以webhook返回给GitHub的信息如下图会出现Service Timeout超时错误,但实际上服务器也成功执行了pull,你可以登陆服务器检查来确认,同时也可以根据你的项目实际情况自行修改webhook.php执行配置.