GIT服务器实现web代码自动部署

之前在一台vps服务器上面搭建了git服务器,用来做代码管理,方便团队开发。但是问题也就相应的来了,使用git可以轻松的上传代码,而由于做的是web开发,每次还都得到服务器上把代码手动pull或者复制到网页所在的文件夹下,也就比较麻烦,不适合我这种懒人。git提供了hook机制,可以很容易的实现代码的自动部署。

个人原创,版权所有,转载请注明原文出处:

http://www.embbnux.com/2014/09/05/git_server_let_code_auto_deploy/

一 git机制简要介绍

git使用的是代码仓库,git服务端有仓库,称为远端仓库,我们clone下来的,本地也有一个仓库称为本地仓库。我们commit的时候是把代码提交到了本地仓库,push时,是把代码提交到了远端仓库。pull的时候是把代码从远端仓库下载到本地仓库。

代码仓库对代码的存储使用了版本指针,每个提交的版本都对应一个HEAD指针,当前版本指针随着代码的提交而一直改变。

二 自动部署原理

说说现在代码的分布情况,开发者电脑上的本地仓库,git服务器上的远端仓库,web服务器上的另一个本地仓库,我们浏览器访问的就是这里的代码。

要实现自动部署,就是要当开发者从本地仓库提交代码到远端仓库的时候,自动把代码部署到web服务器的本地仓库,实现开发者本地仓库和web服务器的本地仓库的同步。

三 实现自动部署

按照上面说的,就是要在开发者提交的时候,自动触发脚本,脚本去实现web端代码的部署.

这里就得讲一下git的hook机制,当git服务器接到各种事件时触发,这里使用的hook是

post-receive

这个hook在git服务器受到push请求,并且接受完代码提交时触发。

具体代码体现:

在git远端仓库的hooks目录下新建post-receive文件:


#!/bin/sh

#author: embbnux
#Blog of Embbnux: http://www.embbnux.com

#判断是不是远端仓库
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
DeployPath="/var/web"

echo "==============================================="
cd $DeployPath
echo "deploying the test web"

#git stash
#git pull origin master
git fetch --all
git reset --hard origin/master

time=`date`
echo "web server pull at webserver at time: $time."
echo "================================================"

保存后赋予可执行权限:


chmod +x hooks/post-receive

这样在开发者提交代码的时候,就会自动部署。

自动部署的时候,我这里使用的是git fetch,也可以使用git pull实现,这里两个的区别主要是pull事先fetch后然后再用merge,来合并本地和远端的代码。但是有个问题,如果开发者在提交过程出现失误,使用git reset复位后,现在远端的代码版本低于web端的代码版本,再使用pull的时候就不能实现和开发者本地的代码的同步。所以这里使用fetch后,在强制使用reset实现web端的代码版本指针和git服务端的一致。由于没有使用merge,所以以后web端的代码就不能在服务器上直接更改了,对web端代码的各种改变都应该使用开发者电脑进行代码提交,不然会报错。

参考:

http://argcv.com/articles/2078.c

http://blog.csdn.net/a06062125/article/details/11727273

《GIT服务器实现web代码自动部署》上有15条评论

  1. Writing objects: 100% (3/3), 256 bytes | 0 bytes/s, done.
    Total 3 (delta 0), reused 0 (delta 0)
    remote: ===============================================
    remote: deploying the test web
    remote: Fetching origin
    remote: Permission denied, please try again.
    remote: Permission denied, please try again.
    remote: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
    remote: fatal: The remote end hung up unexpectedly
    remote: error: Could not fetch origin
    remote: HEAD is now at 43ffaa0 test hook6
    remote: web server pull at webserver at time: 2014年 12月 01日 星期一 17:18:35 CST.
    remote: ================================================

    这是怎么回事呢???

  2. 您好,实现不懂自动部署是怎么回事。是有提交的时候,远端仓库会执行一个hooks文件吗,然后在这个文件里能去访问web端,执行相应的部署脚本吗

  3. 握想请教一个问题:
    post-receive这个脚本访问web端,然后在web端执行相应的操作吗?

      1. 你可以先用echo等基本语句看看有没有执行hook调试一下,post-receive脚本要给它执行权限,chmod +x post-receive,还可能是权限问题,部署的位置如果和git服务器同一个机器的话,要注意用户权限问题,确保部署的用户有git仓库获取的权限,post-receive是以git用户执行的,必要时要su切换到部署用户。不在同一台机器要用ssh,确保git用户有能登录到部署服务器的公钥。

  4. >>>pulling
    remote: Permission denied, please try again.
    remote: Permission denied, please try again.
    remote: Permission denied ().
    remote: fatal: Could not read from remote repository.
    remote:
    remote: Please make sure you have the correct access rights
    remote: and the repository exists.
    remote: deploy done
    remote: fine

    1. 求助:
      上面是post-receive脚本执行打出的信息。这个脚本如下:
      ——-post-receive脚本———————-
      #!/bin/sh

      unset GIT_DIR
      NowPath=`pwd`
      echo “now path is :”$NowPath
      DeployPath=”/d/www2/hello”
      echo “deploy path is :”$DeployPath
      cd $DeployPath
      echo “cd deploy path”

      git branch

      cat .git/config
      echo ‘>>>pulling’

      git pull origin master # pull data from master
      # the follow line is also ok:
      echo “deploy done”
      cd $NowPath
      echo “fine”
      # — Finished
      exit 0
      ——-post-receive脚本结束———————-
      这个脚本,登录到远程服务器上hooks目录下,手动执行是没问题的,所以应该不是脚本内容的问题。
      而在开发机器上提交代码,始终有permission denied问题。

      1. git的权限问题,git hook应该是以git用户去执行的,你要是git用户有从仓库pull的权限,即要把git用户的公钥上传

    1. 我这个方案里 git server 和 web server 是在同一个 server, 所以直接用 git hook 就可以了,比较简单。要是不在同以服务器建议使用 CI, 比如 jenkins 等,都是有 webhook.

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

Time limit is exhausted. Please reload the CAPTCHA.

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据