Avisi Blog

Staging deployments with GIT

Geschreven door Gert-Jan van de Streek | 12 January 2012

 

Git is a great way to implement deployments to your staging environments. It is flexible, fast and efficient. It is ideal for development and test environments that require fast roundtrips (while acceptation and production environments may require a more rigid process). Here's a quick setup guide...


Setup

To create a git setup on your server that can be used by multiple team members, follow these steps:

(Debian Linux example)

git init --bare --shared=group
git config receive.denyDeleteCurrent false
echo "development repository" > description
chmod go+w -R <git_repository>
chmod go+s -R <git_repository>
chown <git_user>:<git_group>. -R <git_repository>

Make sure your deployment users are in the group git-group-name. The denyDeleteCurrent configuration is set to false, this makes it possible to delete branches. That is required because developers with local repositories in various states need to be able to push to this development repository (also see below).

Configure a git hook to run when developers share code to this repository. Create a file called 'post-receive' in the/hooks directory. This is what you can put in there:


if git rev-parse --verify HEAD >/dev/null 2>&1
then
sudo -n -u www-data /build_and_install.sh
fi

This run a local build/install script as user www-data. Because various developers are going to push to this repository we need to sudo to a shared user. This user is probably running your software or website anyways and is needed to stop / start the services. You will probably need a sudoers entry to enable this:


DEPLOYMENT_USERS DEV_SERVER=(ALL) NOPASSWD:/build_and_install.sh

In your build_and_install script you can do anything you like to build and install whatever your creative work of art is.


echo building and deploying application on DEV \(as `id -nu`\)
set -e

# Just because we can and it is really, really fast, we git clone every time:
rm -r git_clone
git clone git_clone

# Build your project here, for example
cd git_clone/<project> mvn package -DskipTests

# stop services if required
/etc/init.d/<service> stop

# Install your project here, for example
tar -zxvf target/*.tar.gz /opt/your_work_of_art

# start services if required
/etc/init.d/<service> start

That's it. You have a shared repository, that runs your build and install script on the development server.

Deploying

Make the server known to your local repository.


git remote add dev <your_dev_server>:<git_repository>

Push your art to the development server


git push dev master

And watch your script running. The output is sent to your local git command.

Non-Fast-Forward Rejections

Since you are not the only one on your team that is pushing to the development server, you might see errors like:

! [rejected] master -> master (non-fast-forward)
error: failed to push some refs ...'

These can simply be resolved by deleting the branch and pushing again:

git push dev :master
git push dev master

Note the colon on the first line.

As always, questions and comments are welcomed!