山海之间

Git钩子实现自动部署

Git钩子实现自动部署
2020-03-20 · 5 min read
Git hook 自动部署

记录一下使用Git钩子来实现网站的自动部署

概念

  • 本地仓库:平时开发所在的环境,可以简单的理解为自己的电脑,记为L1

  • 远程git服务器:git服务所在的服务器,比如我们自己内部搭建的gitlab服务运行在31服务器上,记为G1

  • 远程仓库: 运行仓库代码运行所在的服务器,比如我们的webserver运行的服务器,记为R1

在这里,我们的G1R1恰好是同一台机器

准备

假设G1上已经有存在的仓库webserver,并且在L1R1上都已经有通过git clone命令下载过来的版本一致的代码。并且R1上运行webserver的用户为user1

ssh免密登录

首先要实现运行git服务的用户(用户git)和user1ssh 免密登录。即git可以通过

ssh user1@xxx.xxx.xxx.xxx 

直接登录user1

git用户下,运行命令

ssh-keygen

会在githome目录下生成私钥和公钥文件:

~/.ssh/id_rsa  #私钥
~/.ssh/id_rsa.pub  #公钥

如果home目录下已经存在密钥文件,则不需要重新生成。否则以前生成的密钥会失效!

git用户的公钥添加到user1~/.ssh/authorized_keys中,即

cat ~/.ssh/id_rsa.pub >> /home/user1/.ssh/authorized_keys #权限问题,这个命令不会成功,自己实现相同的结果即可

然后在user1下修改authorized_keys的权限:

chmod 600 ~/.ssh/authorized_keys

再回到git用户下,执行:

ssh user1@xxx.xxx.xxx.xxx 

不用输入密码,即可直接登录user1用户

拉取更新脚本

user1用户下,新建一个脚本,实现从仓库拉取更新的功能,示例如下:

#!/bin/sh

DeployPath="/mnt/analysis/tests/test_uesr1/tmp/webserver"  #远程仓库路径
cd $DeployPath

IS_BARE=$(git rev-parse --is-bare-repository)
if [ -z "$IS_BARE" ]; then
echo >&2 "fatal: post-receive: IS_NOT_BARE"
exit 1
fi

unset GIT_DIR

echo "=========================="
echo "deploying the webserver"

git fetch --all  #使用fetch,不会自动merge
git reset --hard origin/master #强制和远程仓库保持一致

time=`date`
echo "webserver fetch at time: $time."
echo "=========================="

可以将此脚本放在'home目录下,命名为git_fetch.sh

钩子的实现

git服务在服务器上会有相应的目录,在该目录下会有所有用户的所有仓库信息。因为我们要实现的是服务端钩子,所以需要在git服务的服务器上设置。

在我们的G1上运行的是gitlab服务,路径为:

 /var/opt/gitlab

注意git用户的home目录也在该路径下

在该路径下的git-data/repositories目录保存的就是仓库信息。进入我们需要设置钩子的仓库,比如:

/var/opt/gitlab/git-data/repositories/user1/webserver.git

在这个目录下,有一个hooks目录,这是一个软连接,里面是全局钩子。这里的钩子修改,所有的仓库都会执行。
因为我们只想设置单独的仓库,所以我们需要在当前仓库新建一个custom_hooks的目录,这个名称是写死的,不能用其他名称。
custom_hooks下新建post-receive文件,名称同样是定死的。这个名称的钩子代表push之后执行的动作:

mkdir custom_hooks #/var/opt/gitlab/git-data/repositories/user1/webserver.git/custom_hooks

cd custom_hooks
vim post-receive # 注意是横扛,不是下划线

post-receive里写以下命令:

#!/bin/sh

ssh user1@xxx.xxx.xxx.xxx  "sh ~/git_fetch.sh"  #即登录user1,然后user1执行拉取更新的脚本

以上新建文件夹和文件的步骤如果是用root或者其他非git用户操作的,操作完后需要把所有者改成git

chown -R git:git custom_hooks
chmod -R 777 custom_hokks  # 755应该也可以

到此钩子的设置就完成了。接下来在本地L1修改完代码push到远程仓库后,R1上的代码也会自动从远程仓库拉取更新。

总结

工作流程其实很简单,主要是要分清各个角色执行的功能。

  1. L1修改代码,然后push给远程仓库,即G1
  2. G1上的仓库有post-receive钩子,但是执行用户是gitgit用户无权限对user1的仓库进行操作,所以通过ssh的方式登录到user1执行拉取更新的操作

本文首发于公众号:柠檬培养师(ID: yantinger90),欢迎关注!

Powered by Gridea,浙ICP备17039354号-1,© 2019 - 2020🍋