Deploy your website using git and rsync

February 23, 2015

Git has a nice hook feature which you can use to do all kinds of nice stuff with. In this example your code will be deployed to the staging/production server when the code is pushed to the central git repository.

$ vim GIT_DIR/.git/hooks/post-recieve

Here’s an example I use:

#!/bin/bash
TMP_FOLDER="project"
STAGING_PATH="webuser@stagingserver:/var/www/project_root"
PROD_PATH="webuser@productionserver:/var/www/project_root"
EXFILE="/var/lib/gitolite/project.exclude"

CHECKOUTDIR="/var/lib/gitolite/checkouts"

while read oldrev newrev ref
do
  branch=`echo $ref | cut -d/ -f3`

  if [ ! -d "${CHECKOUTDIR}" ]; then
    mkdir ${CHECKOUTDIR}
  fi

  CHECKOUTDIR="${CHECKOUTDIR}/${TMP_FOLDER}"
  if [ ! -d "${CHECKOUTDIR}" ]; then
    mkdir ${CHECKOUTDIR}
  fi

  CHECKOUTDIR="${CHECKOUTDIR}/$branch"
  if [ ! -d "${CHECKOUTDIR}" ]; then
    mkdir ${CHECKOUTDIR}
  fi

  if [ "production" == "$branch" ]; then
    git --work-tree=${CHECKOUTDIR}/ checkout -f $branch
    echo 'Checkout complete. '
    rsync -auv -e ssh --group=www-data --chmod=a+rwx,g+rwx,o+r --delete ${CHECKOUTDIR}/     $PROD_PATH --exclude-from $EXFILE
    echo 'Changes pushed to the PRODUCTION server.'
  fi

  if [ "staging" == "$branch" ]; then
    git --work-tree=${CHECKOUTDIR}/ checkout -f $branch
    echo 'Checkout complete. '
    rsync -auv -e ssh --group=www-data --chmod=a+rwx,g+rwx,o+r --delete ${CHECKOUTDIR}/  $STAGING_PATH --exclude-from $EXFILE
    echo 'Changes pushed to the STAGING server.'
  fi

  rm -rf ${CHECKOUTDIR}
done

Make sure you make this file executable.

$ chmod +x GIT_DIR/.git/hooks/post-recieve

For this script to work using rsync, you will need to setup a rsync on both servers and configure these servers to connect using ssh keypairs. Do this by generating a ssh key on the repo server. Generate this key without a password.

$ ssh-keygen ~/.ssh/git_server

Copy the public key (git_server.pub) over to the staging and production server and place it in ~/.ssh/authorized_keys (one key per line). Edit your repo server’s ssh config file (~/.ssh/config) and add thes lines.

Host productionserver
IdentityFile ~/.ssh/git_server

Host stagingserver
IdentityFile ~/.ssh/git_server

You can test this setup by connecting to the server using the defined names.

$ ssh webuser@servername

This should get u onto the server without any problem.

Use the EXFILE to exclude files from being deleted on the staging or production server. Create one exclude per rule.

logs
files

Hope you bring it to good use.

comments powered by Disqus