设置git post-receive钩子

7
我正在尝试按照指南http://jekyllrb.com/docs/deployment-methods/设置Jekyll部署的git post-receive hook,但是我觉得有些困难。在链接中,有一个段落如下:
为了让远程服务器在每次使用Git推送更改时处理部署,您可以创建一个用户帐户,该用户帐户具有所有已授权进行部署的公钥,这些公钥位于其authorized_keys文件中。完成此操作后,可以按照以下方式设置post-receive hook:
问题1:我不清楚“用户帐户”应该在哪里创建(在Github上?在远程服务器上?)以及(问题2)这个authorized_keys文件在哪里。我的本地计算机主目录中有一个known_hosts文件,其中包含github等密钥。那是authorized_keys文件吗?
接下来的说明告诉您如何设置post-receive hook。
laptop$ ssh deployer@myserver.com
server$ mkdir myrepo.git
server$ cd myrepo.git
server$ git --bare init
server$ cp hooks/post-receive.sample hooks/post-receive
server$ mkdir /var/www/myrepo

我对指令mkdir myrepo.git的含义有些不清楚。例如,我将我的Jekyll网站放入本地Git版本控制中,它给了我这个路径/Users/me/Sites/nginxjekyll/_site/.git/

问题3)那么,这是否意味着我应该在远程服务器上创建一个目录mkdir /Users/me/Sites/nginxjekyll/_site/.git/,跟随mkdir myrepo.git指令?接下来说:

   cp hooks/post-receive.sample hooks/post-receive

然而,我没有hooks/post-receive.sample文件可以复制?在我的本地git仓库中,我有一个post-update.sample但没有post-receive.sample。此外,当我在远程服务器上创建目录mkdir /Users/me/Sites/nginxjekyll/_site/.git/时,它没有在其中创建post-update.sample文件。如果您有时间,您能为我澄清这些说明吗?先谢谢了。
1个回答

7

问题1:他们指的是远程服务器上的用户。

问题2:这取决于两种情况:1. 您需要将本地用户的公钥添加到推送到远程服务器的公钥列表中。2. 如果需要使用ssh部署到另一台服务器,则需要向运行post-receive挂钩的本地用户添加公钥。最有可能只涉及到第一种情况,而不是第二种情况,因为远程服务器将容纳远程git存储库和www服务器。

这意味着您需要将公钥添加到Linux/Unix环境中的authorized_keys文件中。该文件通常位于/home/$USER/.ssh/authorized_keys。authorized_keys文件与用户的known_hosts文件位于同一目录中。

问题3:他们正在解释如何设置远程git存储库。它不需要与您的本地存储库在相同的路径上。

现在来澄清实际发生了什么。教程正在教你如何设置一个远程存储库,每次推送时都会部署jekyll安装。

这意味着如果您有一个github存储库,则不能在那里设置服务器端挂钩。而是在远程服务器上设置一个新的远程。因此,假设您登录到您的服务器(通常使用ssh),运行pwd以了解您的完整路径或在环境变量中设置它:

$DIR=`pwd`

现在您可以在此服务器上创建裸仓库:
git init --bare $DIR/<SOMEDIRNAME>.git

现在你在服务器上有一个远程裸的git仓库。接下来,您需要添加钩子,以允许其在收到推送时部署Jekyll站点。您列出的网站有一个相当简单的部署,但基本上它所做的就是使_site目录成为提供的HTML页面,您可以使用多种方法来实现此目的,我建议您尽可能少地干扰用户,以下是可能完成此操作的示例脚本:

#!/bin/bash
# Assuming a directory structure for www:
# $www_root/releases 
# $www_root/shared
# $www_root/current
# all releases go in releases dir as timestamps dirs
# any logs or other shared items go in shared dir - shared/logs
# current is a symlink to latest release
unset GIT_DIR
WWW_ROOT=/PATH/TO/WWW
REPO_PATH=/PATH/TO/REPO
REPO_BRANCH=master
SITE_DIR=/PATH/TO/_SITE/DIR/IN/REPO
DATE=$(date +"%Y%m%d%H%M")

# get code
if [ ! -d $WWW_ROOT/shared/git_maint ]; then 
  mkdir -p $WWW_ROOT/shared/git_maint
  cd $WWW_ROOT/shared/git_maint
  git clone $REPO_PATH $WWW_ROOT/shared/git_maint
  git checkout master
else
  cd $WWW_ROOT/shared/git_maint
  git pull
  git checkout master
fi

# do deploy
if [ ! -d $WWW_ROOT/releases/$DATE ]; then mkdir $WWW_ROOT/releases/$DATE; fi 
cp -ar $WWW_ROOT/shared/git_maint/$SITE_DIR $WWW_ROOT/releases/$DATE
ln -snf $WWW_ROOT/releases/$DATE $WWW_ROOT/current

exit 0

类似这样的部署方式非常好。如果将此脚本保存在裸仓库的hooks/post-receive文件中,它将在每次推送到仓库时运行。只需记得将其设置为可执行:chmod 755 hooks/post-receive。因此,如果您使用以下命令将此新远程添加到 git 仓库:

git remote add DEPLOY_PROD user@remote.server.com:/path/to/bare/repo

然后输入git push DEPLOY_PROD - 它会推送到你的远程仓库,然后你的远程仓库将触发它的post-receive挂钩(hook),然后将裸仓库复制到几乎任何时候都可以删除的维护目录(maintenance directory)中。然后,该目录用于将站点目录(cp the site dir)复制到一个发布目录(releases dir),然后将其链接到主目录。
当然,所有这些最有可能是过度的,你可以只创建一个部署脚本(deploy script),在本地主机上运行以执行所有这些操作。
问题是你无法直接从github运行服务器端挂钩(hooks),因此你必须想办法解决它。我建议你查看capistrano作为部署策略 - 当前/releases/shared dirs和git_maint dir取自他们的方案,效果很好。
如果你需要帮助,请告诉我,我在开发部署和自动部署策略方面拥有丰富的经验,因此根据你的情况,事情会有所不同。

谢谢,我会尝试一下并告诉你它的效果如何。感谢你的帮助。 - Leahcim
Git仓库的hooks目录中没有post-receive文件。只有applypatch-msg.sample post-update.sample pre-commit.sample pre-rebase.sample commit-msg.sample pre-applypatch.sample prepare-commit-msg.sample update.sample这些文件。 - Leahcim
你可以创建这个文件 - 它只是一个脚本,将在 git 接收到包后运行。只需将其命名为 post-receive - git 将完成其余工作。 - Michael
1
并通过“chmod +x post-receive”使其可执行。 - Mustafa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接