小计 -- 在git bare裸库中增加post-receive 脚本实现线上自动部署

先说一下应用场景:经常会有这样的应用建议上线方式 ,在线上服务器上安装一个bare git库,把上线版本push到这个线上的bare git库。然后,在线上把这个bare git库checkout 出来,部署到相应的应用目录中。最后这一步,是可以用git hooks 自动化完成的。

实现更新的步骤:

用户本地git库 —-push—-> 服务器端裸git库—-receive—->触发HOOKS (./git/hooks/post-receive) —git checkout -f —> 部署到应用目录

实现脚本一

在线上的 bare裸库test中(生成裸库命令 git init –bare test),增加下面的post-receive文件 ./git/hooks/post-receive

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/bin/bash
# TRAGET="/home/webuser/deploy-folder"
# GIT_DIR="/home/webuser/www.git"
BRANCH="master"
TRAGET="/tmp/test"
GIT_DIR="/data/git/test"

while read oldrev newrev ref
do
# only checking out the master (or whatever branch you would like to deploy)
if [[ $ref = refs/heads/$BRANCH ]];
then
echo "Ref $ref received. Deploying ${BRANCH} branch to production..."
git --work-tree=$TRAGET --git-dir=$GIT_DIR checkout -f
else
echo "Ref $ref received. Doing nothing: only the ${BRANCH} branch may be deployed on this server."
fi
done

实现脚本二

下面的脚本会在用户push数据后同时把数据通过rsync 同步到远程应用服务器上。
有两个不同点:
1、 用户是在自己的windows台式机上用tortoisegit客户端,通过git这个用户通过ssh把数据push上来的(相关如何通过tortoisegit的ssh来向远程git服务器的bare库push数据,请参考 )。

2、 要设置sudo,来让git用户可以进行rsync操作(要配置git服务器的root用户可以直接ssh到远程应用服务器上,怎样实现两台linux服务器ssh 无密码登录),我的git用户的shell是git-shell,具体操作如下:

1
2
3
4
5
# 执行 visudo命令
# 在最后面增加下面二行内容,让git用户可以进行rsync和git 操作,并把Defaults requiretty给注释掉:
## Allow git run post-receive
git ALL=NOPASSWD:/usr/bin/rsync, /usr/bin/git
# Defaults requiretty

./git/hooks/post-receive 的内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/bin/bash
# Author: LarryWu
# Usage: git hook for auto update
# TARGET="/home/webuser/deploy-folder"
# GIT_DIR="/home/webuser/www.git"
HOST="xxx.youdomain.com"
BRANCH="master"
TARGET="/data/gitcheckout/${HOST}/"
REMOTE_TARGET="/data/web/${HOST}/"
GIT_DIR="/data/gitdata/${HOST}.git"
LOG_FILE="/tmp/${HOST}.checkout.log"

echo "==========at `date` do post-recevie hooks ========" >> ${LOG_FILE}
while read oldrev newrev ref
do
# only checking out the master (or whatever branch you would like to deploy)
if [[ $ref = refs/heads/$BRANCH ]];
then
echo "Ref $ref received. Deploying ${BRANCH} branch to production..." >> ${LOG_FILE}
echo "==========at `date` do checkout ========" >> ${LOG_FILE}
sudo git --work-tree=$TARGET --git-dir=$GIT_DIR checkout -f >> ${LOG_FILE} 2>&1
echo "==========at `date` do chown ========" >> ${LOG_FILE}
sudo chown -R www-data:www-data $TARGET
echo "==========at `date` do sync $TARGET to ${HOST}:${REMOTE_TARGET} ========" >> ${LOG_FILE}
sudo rsync -av --exclude .git --exclude .env $TARGET ${HOST}:${REMOTE_TARGET} >> ${LOG_FILE} 2>&1
else
echo "Ref $ref received. Doing nothing: only the ${BRANCH} branch may be deployed on this server." >> ${
LOG_FILE}
fi
done

在服务器端测试新增脚本是否生效

1
2
3
4
5
6
7
8
9
10
11
12
13
# 先clone 这个test 裸库到/tmp目录 ,做为部署目录 ,用来测试脚本是否生效
cd /tmp/ && git clone /data/git/test
# 再clone 这个test 裸库到/root目录 ,用来更新test裸库内容
cd /root && git clone /data/git/test
# 在本地clone库中增加一个aaa.txt文件,并commit
cd /root/test
touch aaa.txt
git add aaa.txt
git commit -m 'add aaa.txt'
# 把更新内容push 回test 裸库
git push
# 查看/tmp/test目录是否有新增加的aaa.txt文件
ls -l /tmp/test

在windows 测试脚本是否生效

用tortoisegit 进行push操作,看是否自动更新到了远程应用服务器的TRAGET目录下面。

坚持原创技术分享,您的支持将鼓励我继续创作!