为什么要用Webhooks来更新代码

  • 服务端的代码,不希望直接在服务器上面做更改,需要有中央仓库做托管管理,也利于协作
  • 某些情况下,不希望给开发人员服务器ssh登录权限
  • 开发时,希望得到更快的上线部署速度,享受git commit & git push & refresh的快感

Webhooks部署时需要考虑的一些因素

  • 现有github,gitlab,oschina等一些托管基本都支持Webhooks,原理都是利用git hooks来做的拓展
  • 什么情况下需要更新代码?根据commit message?根据branch?
  • 更新代码时的执行身份?由什么用户来执行git?

设置Linux服务器

  1. 前提:当前已经登录root用户或者具有sudo权限的用户
  2. 确认即将用于执行git命令的用户,假定我们新增一个用户名git,专门用于跑git命令,那么执行 sudo adduser git,并设置密码
  3. 接下来,将git用户添加到sudo组:sudo adduser git sudo[此步骤非必须]
  4. 假定项目代码放在/www下面,且Owner是git,那么执行sudo mkdir /www && sudo chown -R git:git /www
  5. 由于我们的Webhooks代码是用Nginx + PHP-FPM部署的,那么确认下PHP脚本的运行用户情况:ps aux | grep php-fpm, 确认www-data为我们的运行用户
  6. www-data加到git用户组:sudo usermod -aG git www-data
  7. www-data用户不需要密码就能切换到git用户,并且用git用户的身份执行/usr/bin/git命令,修改sudoers:sudo vim /etc/sudoers,添加一行配置:www-data ALL=(git) NOPASSWD: /usr/bin/git
  8. 允许同组用户新增文件时继承原有文件夹权限位:sudo chmod -R g+s /www[此步骤非必须]
  9. 由于我们希望无密码自动拉取代码,那么gitlab代码也是使用ssh方式来配置连接方式的,且hooks被触发时是通过www-data切换成git用户来执行/usr/bin/git命令,那么实际上git pull等命令使用的SSH key是git用户的SSH key,确保已经将git用户的/home/git/.ssh/id_rsa.pub文件的内容设置到gitlab项目中

实现Webhooks项目的代码

  • 项目文件夹权限设置:
  • 项目生成的日志文件权限情况:
  • nginx配置参考
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
server {
listen 80;

root /www/push-gitlab;
index index.php index.html index.htm;

server_name gitlab.server.com;

#location ~ \.php$ {
location = /githooks.php {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
}

# rewrite请求参数,不直接暴露服务器文件路径
if (!-e $request_filename) {
rewrite /checkout/(.*)$ /githooks.php?name=$1 last;
break;
}

}
  • hooks访问URL会是这样的:http://gitlab.server.com/checkout/gitlab-php-webhooks,将它和上面产生的token一同填入gitlab项目配置,然后尝试一下吧~

  • 在服务端tailf日志文件,可以观察到有类似的日志输出则是成功拉取代码啦,如果没有日志文件产生,或者git log发现也没有更新代码,那么多半是权限问题了