I developed this pattern with mercurial, and have recently adapted it to work with git
Assumed
- You want your production application to be deployed at /data/site/myrailssite on your remote system
- You are running passenger for your rails applications (if you aren’t you should really take a look)
Setting up the production target
First, create a rails user on your production system. This lets your rails app run under a different id than you, or your webserver. Privilege isolation is a good thing.
Next, mkdir /data/site/myrailssite and chown rails /data/site/myrailssite.
Next, su – rails, and cd /data/site/myrailssite && git init
Next, chmod 755 .git/hooks/post-receive
And finally add the following lines to .git/hooks/post-receive.
export RAILS_ENV=production
DIR=`pwd | sed s/.git$//`
cd $DIR && git –git-dir=$DIR/.git –work-tree=$DIR reset –hard && rake db:migrate && touch tmp/restart.txt
Setting your source repo to push to production
On your source repository git remote add production ssh://rails@yourhostname/data/site/myrailssite.
Then, finally git push production master, and you are off. On any future change the push to production will roll the git tree to the newest revision on master, kick off the migrations, and trigger a passenger restart. This is a really handy pattern for making life really easy for deployment, and I’m rolling this through all my project sites as I slowly convert them from mercurial to git.