[后端]gitlab之webhook自动部署

动机

前段时间st0rm23在自己的服务器上搭好了自己的gitlab,现在我准备开搞自己的web项目了。但是如果每次写完都要用一些文件传输的工具上传到自己的服务器就显得很低效是吧,也会降低自己写代码的动力。现在st0rm23就借着自己的gitlab,用一个webhook就可以自动将自己的gitlab上的代码部署到web目录下了。那么这样我们只要push一下代码到master上就可以自动生效了,用浏览器重新访问下网站就可以看了勒( •̀ ω •́ )y。

原理介绍

1、配置gitlab当push动作的时候,访问服务器上的一个链接比如xxx.example.com/boot.php
2、boot.php里面写着一行代码,会让服务器git pull相应项目的代码到web目录。
3、pull结束,代码就在web目录了,我们只要重新访问网站就可以了。

核心就是push的时候,gitlab会调用服务器上的脚本,服务器上的脚本就会从git重新拉取项目文件。当然有一些安全性的设计,下面就来详细地说明。

位置

啥?有同学找不到webhook,进入到某个项目中,然后点配置按钮(有个小齿轮),里面就有一个webhook配置,需要填链接地址和token。

webhook位置

配置服务端

先在服务端生成一对你的SSH密钥,因为之后服务器要用ssh方式免账号密码从gitlab上pull代码。用ssh-keygen在服务器上生成密钥,或者你已经有密钥了就跳过这一步。

$ ssh-keygen

有了密钥之后,复制你的公钥,在你的gitlab profile个人资料里,找到SSH的目录,粘贴保存进去就可以了。这样gitlab上就有了你web服务器的公钥了,就可以正常SSH了。

$ cat ~/.ssh/xx.pub ;这个可以看到公钥,xx.pub就是公钥文件(xx替换成你的文件名),把输出的东西复制到gitlab中
gitlab添加公钥

接着在服务端的相应目录下clone gitlab上的项目。这样就可以将这个文件夹对应到gitlab上的项目。后续的脚本就要根据这个对应关系来用脚本驱动这个git pull。
比如我在/var/www/的目录下git clone了gitlab上的项目,得到了/var/www/html/目录,然后将自己的web服务器nginx解析到/var/www/html/主目录(修改完配置文件之后,记得restart,不然不会生效的)。

git clone [your project address] 

服务端脚本

服务端简易php脚本,只要php脚本在被访问的时候,执行git pull操作就可以从服务器pull代码了。

exec("cd /var/www/html/; git pull"); //先定位到相应目录,然后git pull

当然这个脚本太过简易了,被人恶意访问了怎么办,我们还是要加上一些验证。首先是token验证,访问的时候要有特定的token,我们才可以让这个访问生效,一般这个token可以在gitlab填,这样gitlab访问这个脚本的时候就会带上这个token就能识别出来了。有token还不够,被人知道了咋办,我们还要限制IP访问,只有gitlab服务器的ip我们才可以允许执行。修正完就成了下面这个样子。

<?php
$valid_token = 'secret_token';
$valid_ip = array('127.0.0.1'); //这里填你的gitlab服务器ip
$client_token = $_SERVER['HTTP_X_GITLAB_TOKEN'];
$client_ip = $_SERVER['REMOTE_ADDR'];
if ($client_token !== $valid_token) die('Token mismatch!');
if (!in_array($client_ip, $valid_ip)) die('Ip mismatch!');
exec("cd /var/www/html/; git pull origin master");
//exec("cd /var/www/html/; git pull origin master 2>&1", $output);
//var_dump($output); 这样可以用浏览器调试输出
?>

我们保存成/var/www/script/test.php。/var/www/script/这个目录等下我们是要公开给外部访问的。

服务端脚本地址

我们有了这个脚本之后,要部署到合适的位置。一般不是简单地放在web目录下(这个逻辑上也说不通是不是)。我们在web服务器上开一个端口4567来专门为这个脚本服务。下面以nginx为例。在/etc/nginx/sites-available/default的配置文件末尾加上这段

server {
    listen 4567;
    listen [::]:4567;
    
    server_name example.com;
    root /var/www/script;
    index index.html; 

    location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    }
   
    location / { 
        try_files $uri $uri/ =404;
    }}

然后后检测完,重启一下nginx。

$ nginx -t
$ /etc/init.d/nginx restart

好,这时候就可以愉快地访问example.com:4567/test.php了。如果有东西返回了(一般是token mismatch因为我们根本没填token来访问的),那说明这个脚本架好了。

gitlab配置

好,我们现在已经有访问的脚本链接了,我们现在填到gitlab项目中的webhook一栏,保存下来就可以用了。


gitlab上的webhook配置界面

记得你的secret_token要和你test.php里面的配置一样哦,还有valid_ip地址的地方也要记得填对。如果你都填对了,你就在你本地的项目里新建一个文件,然后push到master分支,就可以在你的服务器web目录下愉快地看到你的项目文件了。这样一个自动部署环境就建好了,愉快地写代码吧少年。

账号权限

s0tm23我一开始兴致满满,觉得这样就可以了呀。结果一试,发现失败了。也不知道为啥,本着白盒测试的心态,代码在手,天下我有,那就手工调试输出看一下什么原因好了。结果发现是因为自己全程操作是在root用户下的,而nginx是运行在www用户下的。这TM就尴尬了,www的权限不够,不但无法访问.git文件(因为是root创建的),访问不到root的密钥连不上git,也无法修改root创建的项目文件。蛋疼死了,那就要用www用户重新走一遍流程。但是之前都做了那么多工作了,于是st0rm23就改了一下权限,让www用户也能正常使用。

找到web服务器执行用户

首先,我们要先找到nginx服务器用的是哪一只用户。先看一下配置文件,就可以看见第一行郝然写着用户是user www;这样我们就知道了exec里面的指令是由www用户执行的。

$ vi /etc/nginx/nginx.conf

如果在nginx.conf的第一行把运行用户改成user root;那么nginx就以root来运行了,所有问题就解决了。但是安全性太差了,人家要是挂个一句话木马什么的估计要乐死了,一进来就是root。所以不能用root呀,我们还是老实地给www配权限吧。

修改目录所有者

我之前一直都是用root操作的,结果www对.git的访问没有权限,/var/www/下的文件也没有修改的权限,这就TM尴尬了,这还怎么部署。所以我直接把整个/var/www/的所有权移交给www用户了,反正这个目录就是www的主目录(后面会提到这是怎么知道的),我们用chown指令修改一下就好了

$ chown -R www:www /var/www/

这样目录就可以移交给www用户了,现在www用户可以访问.git文件了,但是不幸的是www还是没有权限访问gitlab,因为它访问不到之前root的ssh密钥,我们就要切换到www用户,重新配置一下密钥。

切换到执行用户

接着我们我们切换到www用户

$ su www

结果显示“This account is currently not available.”,啥?这不让我登录?别急,这是因为linux连他们登录shell的权利都给剥夺了,我们暂时给www权利就好了。到/etc/passwd中,把www用户的配置修改一下,让他的登录shell变成/bin/bash

;www:x:22:22:www:/var/www:/usr/sbin/nologin
www:x:22:22:www:/var/www:/bin/bash

我们还可以观察到,www的用户是属于www用户组的,他的主目录为/var/www。记一下,待会有用的。然后www用户就有权限了。我们用su www重新切换一次,就会发现你现在是以www用户登录了。

重建密钥

之前生成的密钥是root的,www用户根本访问不到这个密钥,所有它连不上gitlab,提示没有权限访问。我们要重新生成一个,生成的步骤和本文开篇一致,不在缀述。有了密钥体系之后,还要尝试访问一下gitlab,让www记下对方的机器签名(之前我忘了这一步,匪夷所思了半天为啥我有密钥了还显示没有权限访问)。然后你会愉快地发现,www用户可以正常从gitlab访问数据了。再试一试脚本就可以正常使用了。

恢复执行用户的nologin

不要忘了在/etc/passwd中,把www用户的nologin选项恢复回去哟

www:x:22:22:www:/var/www:/usr/sbin/nologin

最后

哈哈哈,这回真的是可以用了,辛苦死宝宝了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容