Ray Yamamoto Hilton
Freelance Mobile Architect & iOS Developer in Melbourne, Australia
~

Using git to deploy

I’ve recently started using Git to deploy to my servers. Anyone who has used Heroku would be familiar with this technique and it feels kinda cool to be able to think of your different environments as just git remotes. I can’t vouch for the appropriateness of this technique in the general case, but I just wanted to make a note on what I’ve found to work for me. Hopefully, others may find this useful.

So, I use GitHub as my main source code repository, but I set up a second repository on the server I want to deploy to, normally in my home directory. First create an empty Git repo:

1
$ git init --bar ~/git/my-repo.git

To trigger a deployment on a push, we define a post-receive hook in this new repository. Hooks allow the you took invoke behaviour on a variety of git events, in this case we are interested in when the repository has successfully received a push.

1
$ vi ~/git/my-repo.git/hooks/post-receive

This is just an example, but the contents of the post-receive hook might look like this for a rack/passenger based web application:

1
2
3
4
5
6
7
8
9
#!/bin/bash

cd /var/ww/my-site
unset GIT_DIR
GIT_WORK_TREE=/var/ww/my-site git pull
GIT_WORK_TREE=/var/ww/my-site git reset --hard
GIT_WORK_TREE=/var/ww/my-site git submodule update -i
bundle install
touch tmp/restart.txt

Of course, this file can contain whatever you want, just make sure you set the executable bit on the file:

1
$ chmod +x ~/git/my-repo.git/hooks/post-receive

All that remains is to push your local repository to the new git repo on your server:

1
2
$ git remote add prod ray@my-server.com:~/git/my-repo.git
$ git push prod master

This is just a simple example, but because you are executing a script on the server, you can basically perform any functionality you like. I don’t know whether this would be a good idea in a large-scale production environment, but the key here is to make the deployments as simple and easy as possible to encourage smaller and more regular changes. Backing it with git enables a basic form of rollback, but anything that is not controlled by git, i.e. database schema state, will still need to be managed separately.