利用WebHook实现PHP自动部署Git代码
利用WebHook实现PHP自动部署Git代码
类型
- coding 钩子
- github 钩子
环境
- 服务端:阿里云虚拟主机(Ubuntu16.04)
- coding 自动部署 WebHook3.0
- Windows 10 开发环境
部署
- 服务器虚拟主机配置
- coding 代码托管配置
- 本地代码提交
服务端配置
1、创建web服务器用户目录这里以www用户为例,不同的环境请根据自己环境自行修改
sudo mkdir /var/www/.ssh sudo chown -R www:www /var/www/.ssh/2、生成公钥(两个)
- git用户公钥(个人公钥通用)
部署公钥(部署公钥用以部署项目, 只针对项目)
其实配置一个个人公钥就可以,也就是通用公钥了
用于git clone时认证权限
ssh-keygen -t rsa -C "Tinywan@gmail.com" # 然后一直回车就行 # 生成的文件通常是 /root/.ssh/id_rsa,如果非root用户请查看提示上的路径4、部署公钥(非必需)
sudo -Hu www ssh-keygen -t rsa # 请选择 "no passphrase",一直回车下去 #sudo cat /var/www/.ssh/id_rsa.pub # 这个只是针对单个项目的 sudo cat /home/www/.ssh/id_rsa.pub # 查看生成的密钥内容,复制全部
5、准备钩子文件-Hu www命令:
-u代表切换到哪一个用户,这里说的是www
-H代表切换HOME环境变量的值,也就是password文件中www用户对应的home目录
在你的站点目录建立一个目录
hook,我这里站点目录为:
/home/www/web/,所有hook文件路径为:
/home/www/web/hook,在
hook目录新建
index.php文件
参考demo
<?php error_reporting(1); // 生产环境web目录 $web_path = '/home/www/web/hook/auto-test'; $user = 'www'; $group = 'www'; //作为接口传输的时候认证的密钥 $valid_token = '1954FD0D6'; //调用接口被允许的ip地址 $valid_ip = array('192.168.14.2','192.168.14.1','192.168.14.128'); $client_ip = $_SERVER['REMOTE_ADDR']; $fs = fopen('./auto_hook.log', 'a'); fwrite($fs, 'Request on ['.date("Y-m-d H:i:s").'] from ['.$client_ip.']'.PHP_EOL); $json_content = file_get_contents('php://input'); $data = json_decode($json_content, true); fwrite($fs, 'Data: '.json_encode($data).PHP_EOL); fwrite($fs, '======================================================================='.PHP_EOL); $fs and fclose($fs); if (empty($data['token']) || $data['token'] !== $valid_token) { exit('aInvalid token request'); } $repo = $data['repository']['name']; $cmd = "cd $web_path && git pull"; shell_exec($cmd);
在
hook目录下建立一个自己coding 项目名(只是为了统一,你可以新建一个其他的):
auto-test
最后的目录结构为:
├── hook │ ├── auto-test │ │ │ └── index.php6、修改目录权限
chmod -R u+x /home/www/web/hook7、域名解析
解析一个域名到Linux系统,使用Nginx做一个代理,nginx虚拟主机配置信息如下:
server { server_name auto.tinywan.com; set $root_path /home/www/web/hook; root $root_path; location / { if (!-e $request_filename) { rewrite ^(.*)$ /index.php?s=/$1 last; } } location ~ \.php$ { fastcgi_pass unix:/var/run/php7.1.9-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; fastcgi_buffer_size 128k; fastcgi_buffers 4 256k; fastcgi_busy_buffers_size 256k; fastcgi_connect_timeout 10000; fastcgi_send_timeout 6000; fastcgi_read_timeout 6000; } }
8、验证的以上域名
auto.tinywan.com已经被A记录到Linux外网IP了,阿里云域名解析
hook钩子目录的
index.php文件可以访问
访问:http://auto.tinywan.com/index.php 输出:error request // 表示可以正常访问9、配置git
git config --global user.name "Tinywan" git config --global user.email "Tinywan@gmail.com" # 邮箱请与conding上一致10、配置公钥
复制:
/home/www.ssh/id_rsa.pub内容到个人设置页
https://coding.net/user/account/setting/keys,【新增公钥】添加即可
id_rsa.pub 文件内容
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABBBABAQChrujULy3U56wS5jLJ0rAJMtv2MNABhbqU1kaiiiyUGFz9+Ndwel8o4dW4whmFRWBodDppc2gpDcF/UM6v7DLzHYOd/38BDp0vRz+zhgZ0BCfyeUV958tpTI6uQyjFil3jwDrKvDqeS4eVnb1fJZfnk/utcFCkVSjhae1sBqM10bkaQmsmwLKr7fN6DeUox9nYkknDqaD645wYplW/qFAXItHOaaZzgTpbAuEb4uss0BCtiutsDFsJwcuXlAsvg4xwsTmagdlz+FhTksCnGALcB10kaz0EY2g9NOHVCqQ4QU4TyNmUVwBHYfj6LAGALO4NAHfwErzKgqfRhBLzDsKB www@Tinywan11、配置 WebHook
选择项目
(auto-test)> 设置 > 【WebHook】 > 【新建 WebHook】 > 粘贴你的
hook/index.php所在的网址:
http://auto.tinywan.com/index.php, 令牌可选,但是建议写上。
稍过几秒刷新页面查看hook状态,显示为绿色勾就OK了
12、服务端初始化项目我们需要先在服务器上clone一次,以后都可以实现自动部署了
sudo -Hu www git clone https://git.coding.net/Tinywan/auto-test.git /home/www/web/hook/auto-test/ --depth=113、Windows客户端
(1)开发端也克隆一份代码
$ git clone https://git.coding.net/Tinywan/auto-test.git Cloning into 'auto-test'... remote: Counting objects: 3, done. remote: Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. Checking connectivity... done.
(2)新建文件
index.php
<?php echo "Hell Coding";
(3)提交本地的代码
$ git add ./ $ git commit -m "test hook" $ git push -u origin master
(4)查看服务端文件是否已经更新
├── auto-test └── index.php
发现目标目录里就刚才提交的
index.php文件了
立即访问:http://auto.tinywan.com/auto-test/index.php
钩子
file_get_contents('php://input')接受的文件内容
{ "ref": "refs/heads/master", "before": "90d67c99a3077a7a6823c50a95275812471ecf47", "commits": [ { "committer": { "name": "Tinywan", "email": "756684177@qq.com" }, "web_url": "https://coding.net/u/Tinywan/p/auto-test/git/commit/3e55e1c6aa0d064ba4fede1556f0e2bb14c0bed3", "short_message": "json_encode($_SERVER)\n", "sha": "3e55e1c6aa0d064ba4fede1556f0e2bb14c0bed3" } ], "after": "3e55e1c6aa0d064ba4fede1556f0e2bb14c0bed3", "event": "push", "repository": { "owner": { "path": "/u/Tinywan", "web_url": "https://coding.net/u/Tinywan", "global_key": "Tinywan", "name": "Tinywan", "avatar": "/static/fruit_avatar/Fruit-14.png" }, "https_url": "https://git.coding.net/Tinywan/auto-test.git", "web_url": "https://coding.net/u/Tinywan/p/auto-test", "project_id": "3351025", "ssh_url": "git@git.coding.net:Tinywan/auto-test.git", "name": "auto-test", "description": "auto-test" }, "user": { "path": "/u/Tinywan", "web_url": "https://coding.net/u/Tinywan", "global_key": "Tinywan", "name": "Tinywan", "avatar": "/static/fruit_avatar/Fruit-14.png" }, "token": "1954FD0D6" }
可能会遇到的问题
1、在网上按照步骤一步一步将公钥和部署公钥配置完成点击跳转参考地址
2、coding上可以成功ping的通,可是阿里云Linux服务器上面没有反应(文件没有自动部署呀)
首先判断hook脚本有没有执行。所以将脚本换成简单的脚本测试
看看是不是文件没有权限或者钩子文件有问题
token 配置无效问题
我已经在这里讨论了配置了token,但是接受不到
如何解决?
coding的最新版本的
WebHook【令牌】验证是和github的验证一样了,把 signature 跟内容相关写在 header 中了
获取签名
$signature = $_SERVER['HTTP_X_HUB_SIGNATURE']
token 生成技巧
如:
https://www.tinywan.com/进行md5加密:
1989BC88338CB4DABEF20BD7C54FD0D6
[success] #### 配置一个共有的webhooks
为了不让每个项目都新建一个钩子
web目录结构
. ├── webhooks-test │ └── index.php ├── hook │ └── auto_hook.log
nginx 配置
server { server_name webhook.tinywan.com; set $root_path /home/www/web/webhook; root $root_path; location / { } location ~ \.php$ { fastcgi_pass unix:/var/run/php7.1.9-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; fastcgi_buffer_size 128k; fastcgi_buffers 4 256k; fastcgi_busy_buffers_size 256k; fastcgi_connect_timeout 10000; fastcgi_send_timeout 6000; fastcgi_read_timeout 6000; } }
coding设置任何一个项目(
webhooks-test)的hook地址为
http://webhook.tinywan.com/index.php
本地提交代码即可测试
[success] #### Github自动部署
对于个人项目而言,有的人项目托管在github上,线上访问地址放在自有服务器上。平时自己开发的话,要先push到github,在到自己服务器上pull下来(服务器上装了git),特别麻烦。
github有个webhook,可以在push之后触发,这样我们就可以利用钩子出发服务器脚本,执行pull命令拉取最新代码了。
配置这个钩子,有几点坑需要提一下
1、我们服务器上的web文件,大多是用户和用户组都是www,所以平时运行那些PHP文件,也都是www用户运行的。那么我们就必须以www用户来吧代码仓库clone下来,然后以www的身份去生成ssh密钥
ssh-keygen -t rsa -C "your_email@youremail.com"
,生成之后记得把公钥放在github里的项目配置里。2、github里有两种请求方式可供选择,一种是表单式post,我们可以正常用
$_POST
接收,还有一种是json式post,PHP只能用php://input
去接收了,每次调取url都是带着密钥的,你需要判断密钥对,在pull,否则任何人都可以pull了
下面是github密钥的算法PHP版本
钩子代码
// Github 配置 $secret = '1989BC88338CB4DABEF20BD7C54FD0D6'; $github_signa = $_SERVER['HTTP_X_HUB_SIGNATURE']; // sha1=e0ec9317f440f3fd47631852ef585c6b2680e8f8 list($hash_type, $hash_value) = explode('=', $github_signa, 2); $payload = file_get_contents("php://input"); $hash = hash_hmac($hash_type,$payload,$secret); // e0ec9317f440f3fd47631852ef585c6b2680e8f8 // Github 验证 if($hash && $hash === $hash_value) { fwrite($fs, $hash.'========== 认证成功,开始更新 '.PHP_EOL); fwrite($fs, $hash.'========== exec("./github_pull.sh") '.PHP_EOL); }
- 3、由于执行shell命令涉及到 php的exec方法,默认是不开启这个方法的,需要你去php.ini开启它
下图是钩子访问url的时候的返回数据
Headers
Connection: keep-alive Content-Length: 22 Content-Type: text/html; charset=UTF-8 Date: Sun, 22 Jul 2018 02:26:23 GMT Server: Tinywan-server/1.0 Strict-Transport-Security: max-age=31536000; includeSubdomains; preload Transfer-Encoding: chunked Vary: Accept-Encoding X-Content-Type-Options: nosniff X-Frame-Options: deny X-XSS-Protection: 1; mode=block
Body
aInvalid token request
为什么我的提交记录不被github记录呢,为什么无法点亮小绿点?
git config --global user.name "your name" //配置用户名和github名称一致 否则不计入提交次数 git config --global user.email "your email" //配置email
[success] 完整的钩子代码(兼容GitHub和Coding)
<?php error_reporting(1); // 配置 $secret = '1989BC88338CB4DABEF20BD7C54FD0D6'; $userAgent = $_SERVER['HTTP_USER_AGENT']; $signature = 'sha1=e0ec9317f440f3fd47631852ef585c6b2680e8f8'; if (substr_count($userAgent, 'GitHub') >= 1) { $signature = $_SERVER['HTTP_X_HUB_SIGNATURE']; } elseif (substr_count($userAgent, 'Coding') >= 1) { $signature = $_SERVER['HTTP_X_CODING_SIGNATURE']; } list($hash_type, $hash_value) = explode('=', $signature, 2); $jsonContent = file_get_contents("php://input"); $checkHash = hash_hmac($hash_type, $jsonContent, $secret); // e0ec9317f440f3fd47631852ef585c6b2680e8f8 $fs = fopen('./auto_hook.log', 'a'); $data = json_decode($jsonContent, true); fwrite($fs, 'Request on [' . date("Y-m-d H:i:s") . '] from [' . $data['pusher']['name'] . ']' . PHP_EOL); fwrite($fs, 'Data: '.json_encode($data).PHP_EOL); fwrite($fs, 'Service '.json_encode($_SERVER).PHP_EOL); // sha1 验证 if ($checkHash && $checkHash === $hash_value) { fwrite($fs, '认证成功,开始更新 ' . PHP_EOL); $repository = $data['repository']['name']; $pwd = getcwd(); $command = 'cd .. && cd ' . $repository . ' && git pull'; fwrite($fs, 'command '.$command.PHP_EOL); if (!empty($repository)) { shell_exec($command); fwrite($fs, $repository . ' 更新完成 ' . PHP_EOL); } $fs and fclose($fs); }阅读更多
- 利用WebHook实现PHP自动部署Git代码
- 利用WebHook实现PHP自动部署Git代码
- CentOS利用WebHook实现PHP自动部署Git代码
- (git)Bitbucket使用WebHook实现自动部署PHP代码
- PHP 结合 WebHook 实现代码自动部署
- php实现webhook自动部署代码
- 利用WebHook实现Github或Coding代码的自动部署
- Php+WebHook实现项目自动部署 - 关于Git自动部署方案
- centos 安装git服务器,配置使用证书登录并你用hook实现代码自动部署
- GitHook+JGit实现最新代码的自动克隆或者项目的自动部署
- git hook实现代码自动部署
- Gitlab利用Webhook实现Push代码后的jenkins自动构建
- git实现代码提交自动部署到相应的web服务器
- git码云配置web hook钩子实现自动部署,git权限等问题,LAMP
- php项目自动部署(利用webhook)
- 使用Git的hook实现代码的自动部署
- Jenkins进阶-Gitlab使用Webhook实现Push代码自动部署(3)
- GIT服务器实现web代码自动部署
- GitHub利用webhook实现push时项目自动部署
- 通过git自动部署WEB服务上的PHP代码,提交即生效