使用git将网站部署到多个环境

时间:2011-09-22 01:56:25

标签: git deployment githooks environments

目前,我使用git将项目部署到生产中,使用git push production master到具有以下post-receive挂钩的存储库:

#!/bin/bash
GIT_WORK_TREE=/home/username/www.example.com/myproject/ git checkout -f

production是一个遥控器,通过git remote add production ssh://server/home/username/projects/myproject.git添加。

但是现在我需要将一个单独的分支部署到服务器上的单独路径。我确实想出了一个解决方案,但我想有更好的方法可以做到。

我所做的是在服务器myproject-alternate.git上创建一个新的存储库,使用类似的post-receive挂钩(用/myproject/替换/myproject-alternate/),用{{添加了这个新的存储库1}}。现在,我可以使用git remote add alternate ssh://server/home/username/projects/myproject-alternate.git部署到备用路径。

这有效,但我有一些问题:

  1. 部署到备用服务器的命令不是我所期望的 - 不止一次我在最后忘记了git push alternate branchname:master并且服务器的存储库收到了一个新的分支并且没有触发后接收挂钩
  2. 我不确定在服务器上创建新存储库是否是最佳解决方案,我想知道更大的项目会发生什么。
  3. 在没有上述问题的情况下,还有其他方法可以完成此部署流程吗?也许更好的post-receive hook使用收到的branchname来部署到正确的路径? (这甚至可能吗?)

2 个答案:

答案 0 :(得分:2)

我写了blog post关于我用来将我的网站部署到登台服务器和实时服务器的设置。你可以做类似的事情。关键是要配置您要在本地存储库的.git/config文件中推送哪些分支,如下所示:

[remote "alternate"]
    url = ssh://server/home/username/projects/myproject-alternate.git
    fetch = +refs/heads/master:refs/remotes/alternate/master
    pushurl = ssh://server/home/username/projects/myproject-alternate.git
    push = refs/heads/branchname:refs/heads/master
[remote "production"]
    url = ssh://server/home/username/projects/myproject.git
    fetch = +refs/heads/master:refs/remotes/production/master
    pushurl = ssh://server/home/username/projects/myproject.git
    push = refs/heads/master:refs/heads/master

这会将其设置为每当您键入

git push alternate

它会自动将本地branchname分支推送到备用存储库中的远程master分支。

但是,由于您的备用和生产工作树位于同一台计算机上,因此您可能只需创建一个存储库并将其签出到两个不同的位置即可。要做到这一点,请忽略前一段,而是将这样的东西放在post-receive hook中:

#!/bin/bash
checkout_alt=
checkout_prod=
while read oldrev newrev refname; do
    case "$refname" in
        ( "refs/heads/branchname" )
            export checkout_alt=1 ;;
        ( "refs/heads/master" )
            export checkout_prod=1 ;;
    esac
done
test -n "$checkout_alt" && GIT_WORK_TREE=/home/diazona/tmp/gittest/alt/ git checkout -f branchname
test -n "$checkout_prod" && GIT_WORK_TREE=/home/diazona/tmp/gittest/prod/ git checkout -f master

(显然你没有 使用if语句)。如果你这样做,我建议将存储库裸露,以便它不存储自己的工作副本,只是为了简单起见。这样,您只需要一个远程,每当您推送master分支时,它将更新生产工作树,每当您推送branchname分支时,它将更新备用工作树

免责声明:我实际上没有对此进行测试,因此请先在测试文件夹中进行测试。如果我发现任何错误,我会回来编辑。

答案 1 :(得分:0)

我还在我使用的设置上写了a blog post,这允许我git push我的项目中的每个分支到我的远程,将每个分支部署到各自的目录中。

例如:

Branch      | Directory on remote
--------------------------------------
master      | /www/foo.com/master
staging     | /www/foo.com/staging
production  | /www/foo.com/produciton

因此,要执行此操作,请将以下函数添加到服务器dotfiles:

function gitorigin() {
    mkdir -p "$1"
    cd "$1"
    git init --bare
    git config core.bare false
    git config receive.denycurrentbranch ignore
    cat <<EOF >hooks/post-receive
#!/bin/bash

while read oldrev newrev ref
do
    branch=\`echo \$ref | cut -d/ -f3\`
    mkdir -p ../\$branch
    git --work-tree=../\$branch checkout -f \$branch
    echo Changes pushed to \$branch
done
EOF
    chmod +x hooks/post-receive
    cd ..
}

在远程,创建存储库:

$ cd /www/foo.com
$ gitrepo foo.git

在本地,推送分支

$ cd ~/Sites/foo.com
$ git remote add origin ssh:///<USER>@<HOST>/www/foo.com/foo.git
$ git push origin <BRANCH>

将您的主分支推送到远程,进入/www/foo.com/<BRANCH>/