Automatic Deployment via git 4

Posted by Michael Fri, 06 Feb 2009 02:00:00 GMT

If you're using git to manage your homepage / blog / little web application, it is relatively easy to add automatic deployment functionality to simplify your work flow. Deploying a new version can then be a simple git push!

For this article, I'll use a Ruby on Rails application as the example. It should be easy enough to adapt this approach to other situations. You can even do more complex actions such as compiling a deployment archive as long as no manual intervention is required.

Let's assume you want to install your RoR application in /srv/web/my_app, and you have a bare git repository on the same server, in /srv/gitosis/repositories/my_app.git. All you need to do is create a clone from the repository in the deployment location, adjust the permissions of the log and tmp directories, configure the database connection if required and then you are done.

Applying updates with git in such an environment is already simple: develop and test on your local machine, eventually push your changes to the server and finally pull the changes into the deployment directory. For example:

client $ git commit ...
client $ git push
client $ ssh server
server # cd /srv/web/my_app
server # git pull
server # touch tmp/restart.txt

This way, your local configuration is also protected by git and will be merged if possible (commit any local changes).

To further automate this, we can use the post-receive hook. In our example this is located at /srv/gitosis/repositories/my_app.git/hooks/post-receive. I have this hook call a script called update-rails.sh with the application name (my_app) as the parameter.

update-rails.sh looks like this:

#!/bin/sh
name=$1
if [ -z "$name" ] ; then
        echo "need to give name of checkout dir on command line"
        exit 1
fi

dir=/srv/web/$name
if [ ! -d $dir ] ; then
        echo "the directory $dir does not exist"
        exit 1
fi

cd $dir
env -i git pull
rake db:migrate
touch $dir/tmp/restart.txt

As you can see, this script will also run any required DB migrations.

Simple, isn't it?

Hosting git repositories

Posted by Michael Sat, 31 Jan 2009 18:57:00 GMT

A bit more on hosting git repositories:

I first tried to simply go with a shared directory on a server, i.e. a directory owned by a specific unix group, the group sticky bit switched on, and all users who are supposed to have access to the repository in that group. This works to some degree, but has some drawbacks as git does not auto-magically handle file permissions correctly. So on a system using a umask of 022 (which I guess is a majority of systems?), newly created files are not writable by the group, only by the user who created the files.

So I decided to go with gitosis, which not only eliminates the file permission problem, but is also a more flexible solution as it doesn't require an actual system user for everyone who is supposed to have access to your git repositories. Instead it relies on your user's ssh keys for authentication plus an ACL to determine read/write access to repositories.

There is already a good setup manual, so I won't repeat everything here. On a server running Debian Etch, it boils down to the following commands (make sure you have the backports repository installed):

# apt-get -t etch-backports install gitosis
# sudo -H -u gitosis gitosis-init < YOUR_PUBLIC_SSH_KEY

That is the setup work required on the server. Then you can clone gitosis' admin repository on your local system:

$ git clone gitosis@YOUR_SERVER_HOSTNAME:gitosis-admin.git

I'll again refer you to the setup manual on how to configure gitosis. Just one thing I stumbled over: When adding new users, make sure that you name the key files correctly. I forgot the .pub extension, and wondered why those users didn't get access...