setting up a git post-receive hook
I’m trying to follow along with the instructions http://jekyllrb.com/docs/deployment-methods/ for setting up a git post-receive hook for Jekyll deployment, however, I’m finding them a little dense for me. At that link, there’s a paragraph that says
To have a remote server handle the deploy for you every time you push
changes using Git, you can create a user account which has all the
public keys that are authorized to deploy in its authorized_keys file.
With that in place, setting up the post-receive hook is done as
How to locate the git config file in Mac Pulling the latest code after merging branches MS git provider in Visual Studio: where do I set push target? Can a Rails app be deployed without using Heroku Toolbelt? If so, how? how to use git from another directory? Why GitHub suggest “prefix your version names with the letter v?”
Question 1: It’s not clear to me where the ‘user account’ should be created (on Github? on the remote server), and (Question 2) where this
authorized_keys file would be. I have a
known_hosts file in my home directory on my local machine with keys for github etc. Is that the authorized_keys file?
The instructions go onto tell you to set up a post-receive hook like this
laptop$ ssh firstname.lastname@example.org 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 is a little unclear to me. For example, I put my Jekyll site into git version control on my local machine, and it gave me this path
Question 3) Does that mean, then, that, following the mkdir myrepo.git instruction, I should create a directory
mkdir /Users/me/Sites/nginxjekyll/_site/.git/ on my remote server? Moving on, it says,
cp hooks/post-receive.sample hooks/post-receive
However, I don’t have a
hooks/post-receive.sample file to copy? In the git repository on my local machine, I have a post-update.sample but not post-receive.sample. Furthermore, when I created the directory mkdir /Users/me/Sites/nginxjekyll/_site/.git/ on my remote server, it didn’t create the post-update.sample file in it.
Can you clarify these instructions for me if you have a moment. Thank you in advance.
One Solution collect form web for “setting up a git post-receive hook”
Question 1: They are referring to the user on the remote server.
Question 2: This depends, two scenarios: 1. You will need to add the public key of your local user to push to your remote server. 2. You will need to add a public key to a the local user who runs the post-receive hook if an ssh is required to deploy to another server. Most likely only 1 is your concern and 2 is not because the remote server will house the remote git repo and the www server.
This means you add the public key to the authorized_keys file in a linux/unix environment. This file is typically located in /home/$USER/.ssh/authorized_keys The authorized_keys file is located in the same directory as the known_hosts file for a user.
Question 3: They are explaining how to setup the remote git repository. It does not need to be at the same path as your local repository.
OK – now to clarify what is actually going on here. The tutorial is teaching you how to setup a remote repository that will deploy a jekyll install every time it is pushed to.
This means that if you have a github repo, you cannot setup the server-side hook there. Rather you would set up a new remote on your remote server. So say that you log into your server (with ssh typically), run
pwd to learn your full path or set it in an environment variable:
Now you can create a bare repo on this server:
git init --bare $DIR/<SOMEDIRNAME>.git
Now you have a remote bare git repository on your server. Next you need to add the hook that allows it to deploy your Jekyll site upon receiving a push. The site you have listed has a rather simple deploy, but basically all it is doing is making the _site dir the served html pages, you could do this several ways, I suggest that you do it without disrupting your users as much as possible, here is a sample script that might do such a thing:
#!/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 -s $WWW_ROOT/new_current $WWW_ROOT/releases/$DATE && mv $WWW_ROOT/new_current $WWW_ROOT/current exit 0
Something like that would be a good deploy. If you save this script on your remote server in the bare repo hooks/post-receive file then it will run each time the repository is pushed to. Just remember to make it executable: chmod 755
hooks/post-receive So if you add this new remote to your git repo with:
git remote add DEPLOY_PROD email@example.com:/path/to/bare/repo
git push DEPLOY_PROD – it will push to your remote and then your remote repo will fire its post-receive hook and then copy the bare repo down to a maintenance directory that can be blown away at almost any point. This directory is then used to cp the site dir to a releases dir and then that is linked up to the main directory.
Of course all of this is most likely overkill and you can just create a deploy script that runs from you local host to do all this over ssh.
The problem is you are unable to run server side hooks directly from github for this methodology so you have to work around it. I would suggest you check out capistrano as a deployment strategy – the current/releases/shared dirs and git_maint dir is taken from their schema, it works well.
Let me know if you would like any help here, I have a lot of experience developing deploy and automated deploy strategies, so depending on your situation, things will vary.