使用 Git Hook 实现网站的自动部署

自动化能解放人类的双手,而且更重要的是,因为按照规定的流程来走,也减少了很多误操作的产生。不知道大家平时都是怎么样更新自己生产环境的代码的,FTP 覆盖旧文件、服务器定时任务去 build 最新的源码,还是有更高级的做法?

目前我在使用 Git Hook 来部署自己的项目。Git Hook 是 Git 提供的一个钩子,能被特定的事件触发后调用。其实,更通俗的讲,当你设置了 Git Hook 后,只要你的远程仓库收到一次 push 之后,Git Hook 就能帮你执行一次 bash 脚本。

Git的挂钩(Hook)主要包含:

  • applypatch-msg
  • post-update
  • pre-rebase
  • commit-msg
  • pre-applypatch
  • update
  • post-commit
  • pre-commit
  • post-receive
  • prepare-commit-msg

这里我们只需要使用 post-receive 这个 Hook:在接收 post(push)请求之后执行。

下面是我使用 Git Hook 进行简单的自动化部署,可能还有更高级的做法,大家自己去挖掘。

服务器上需要配置两个仓库,一个用于代码中转的远程仓库(testRepo),一个用于用户访问的本地仓库(testDeploy)。这里的「远程仓库」并不等同于托管代码的「中央仓库」,这两个仓库都是为了自动同步代码并部署网站而存在。

git_deploy

一、在服务器初始化一个远程 Git 仓库(此仓库仅仅作为一个部署中转仓库,无其它用)

git initgit --bare init 初始化出来的仓库是完全不一样的,参考:http://blog.haohtml.com/archives/12265

这里我们要通过 git --bare init 初始化一个远程仓库

$ cd ~
$ mkdir testRepo
$ cd testRepo
$ git --bare init

在服务器初始化一个本地 Git 仓库。

在初始化远程仓库时最好使用 git –bare init   而不要使用:git init
如果使用了git init初始化,则远程仓库的目录下,也包含work tree,当本地仓库向远程仓库push时,   如果远程仓库正在push的分支上(如果当时不在push的分支,就没有问题), 那么push后的结果不会反应在work tree上,  也即在远程仓库的目录下对应的文件还是之前的内容,必须得使用git reset –hard才能看到push后的内容.

二、在服务器初始化一个本地 Git 仓库

这个仓库就是通过 git init 初始化出来最常见的本地仓库,它的作用是拉去远程仓库(其实就在它旁边)最新的源码,然后在这个仓库里进行编译,把代码编译到 www 目录(网站的根目录)。

$ cd ~
$ mkdir testDeploy
$ cd testDeploy
$ git clone ~/testRepo #从远程仓库 clone 出源码,我测试的直接clone使用 git --bare init初始化的仓库,没有办法使用,会提示没有.git目录而出错。
$ git init
$ git remote add origin user@server.ip:/home/user/testRepo #只能手动git init,然后再git remote add origin user@server.ip:/home/user/testRepo 才可以。
$ git pull origin master

为远程仓库设置 Hook,编辑
post-receive(如果没有自行创建),post-receive 代码请看:http://gist.github.com/566767

$ cd ~/testRepo/hooks
$ vim post-receive

post-receive 里面的执行脚本

#!/bin/sh
unset GIT_DIR
DeployPath=/home/user/testDeploy
WwwPath=/home/wwwroot/testDeploy

cd $DeployPath
git add . -A && git stash
git pull origin master

# 下面这2步都是按照实际你自己添加的bash脚本
fis release -Dompd $WwwPath # 我使用的FIS,对前端代码进行编译
qrsync /home/user/qiniutools/config.json # 使用七牛同步工具进行同步

或者直接使用以后原生类似的语句

#!/bin/sh

unset GIT_DIR

NowPath=`pwd`
DeployPath="../../www"

cd $DeployPath
git pull origin master

cd $NowPath
exit 0

最后,为 post-receive 添加可执行权限

chmod +x post-receive


三、为本地仓库添加 中转部署git仓库 源(开发机)

这次的本地仓库就真的是你开发机上面的本地了。在你原有 Git 项目里面添加一条新的 remote 源,以后往这个 remote 源里面 push 代码就会自动触发上面那 bash 脚本了。

$ git remote add deploy user@server.ip:/home/user/testRepo
$ git push deploy master

相关教程:http://segmentfault.com/a/1190000003836345