通过gitee钩子自动部署php代码

首先去gitee下登录账号,进入设置页面(右上角头像鼠标悬停下拉菜单中的设置)

点击SSH公钥,然后去服务器上生成一个公私钥,(直接基于root账号生成即可,之后需要改变)

ssh-keygen -t rsa -C "xx@xx.com"

其中xx.xx.com是你的gitee账号的登录邮箱,然后点三次回车会在~/.ssh/目录下生成了一对公私钥,id_rsa,id_rsa.pub,打开id_rsa.pub公钥文件,将里面的所有内容复制处理然后去gitee中的SSH公钥页面中粘贴确定

 

 标题不需要管,会自动生成。然后去服务器中执行命令:

ssh -T git@gitee.com

得到如下反馈,代表成功:

Hi nickname! You've successfully authenticated, but GITEE.COM does not provide shell access.

然后就可以跳转到web跟目录去拉取代码了,此时就可以基于ssh方式拉取:

git clone git@gitee.com:xx/xx.git

将代码全部拉取下来之后,就该去为www用户设置pull的权限了,因为网站自动化部署都是基于www用户去执行的,而非root用户,所以需要把root用户的.ssh目录复制一份给www目录:

cd /home/www
cp -aR ~/.ssh .

复制成功之后,需要把这个目录的所有者全部赋给www:www用户才行,不然www用户无权使用这些文件

chown -R www:www .ssh/

这里不需要再做chmod操作,需要保证之前生成的私钥文件的权限是600,不然拉取同步代码时会失败。

 

然后编写钩子方法:

 1      if(substr($_SERVER['REMOTE_ADDR'],0,10) != '106.13.250') {
 2             echo '非法IP:' . $_SERVER['REMOTE_ADDR'];
 3             exit(0);
 4         }
 5         // 获取请求参数
 6         //$headers = getallheaders();
 7         $body = json_decode(file_get_contents("php://input"), true);
 8         // 请求密码
 9         $password = 'pwd';
10         // 验证提交分支是否为master
11         if (!isset($body['ref']) || $body['ref'] !== 'refs/heads/master') {
12             echo '非主分支' .($body['ref']);
13             exit(0);
14         }
15         // 验证提交密码是否正确
16         if (!isset($body['password']) || $body['password'] !== $password) {
17             echo '密码错误';
18             exit(0);
19         }
20         // 验证成功,拉取代码
21         $path = $body['project']['path'];
22         $result = $this->pull('git_pull', $path);//伪代码,调用nodejs
23         echo 'git pull执行结果:' . $result;

 

 

并且将钩子方法的全URL复制到项目的webhook地址中,此时如果提交代码做测试,那么可能会出现下面的问题:

 

insufficient permission for adding an object to repository database ./objects

 

这个问题是因为项目目录下的.git目录中的文件没有归给www:www用户,解决方法是:在项目根目录下执行chown -R www:www .git

需要注意,在服务器上生成公私钥之后,去gitee上绑定公钥之后,需要把.ssh目录拷贝到/home/www目录下面,并且把目录归给www:www用户,且给里面的文件的权限是600

再就是可以使用php的shell_exec函数去执行git pull指令去同步代码,但需要在php.ini解锁这个函数,这样有一定的安全隐患,

所以可以让php做前置拦截,(比如目标服务器的IP判断和hook密码),过了验证再调用nodejs的api,通过nodejs的exec命令执行sh文件,在sh文件中去做cd目录和git pull拉取,这样相对就安全很多

笔者使用的是nodejs当下比较流行的koa框架,基于restfulApi去调接口执行,需要注意的是操作shell时需要安装的特定优化包,再就是使用shell时不能随意写,比如cd到任意的一个目录下去执行命令,而只能在项目跟目录下去执行一些py或者sh脚本。

cnpm i --save child-process-promise

代码:

const { exec } = require('child-process-promise');
const { stdout, stderr } = await exec('sh a.sh');

 shell脚本:

echo "git pull:"
cd /home/www/xx
git pull 2>&1
chown -R www:www /home/www/xx

 

posted @ 2022-07-30 18:08  童年的回忆  阅读(806)  评论(0编辑  收藏  举报
如果本博客解决了您的问题,可以微信支付宝打赏鼓励一下作者哦,在此表示感谢