Deploying with Git. Simple & Effective

Deploying with Git. Simple & Effective

Deployment can be a pain, but it does not have to be. We at ForwardMX use Git and a post-receive hook to deploy our Rails app to Phusion Passenger.


To avoid further negative comments, please keep in mind that this is deployment only. Obviously we have a different development workflow with CI and Gitlab. And you should too!

In a quick blog post we want to show you how we deploy with Git. We saw crazy methods of doing this, heavy third party tools and a lot of other crazy tactics to make deployment easy. But we do think that is not necessary, keeping things simple is the way we like to work.

Our file structure looks like this:

[email protected]:/var/www/forwardmx$ ls -l
insgesamt 8
drwxr-xr-x 14 rails rails 4096 Jan 18 10:18 code
drwxr-xr-x  7 rails rails 4096 Jan 19 15:03 git

code is the directory where the Rails app resides powered by Phusion Passenger. git is a bare repository we created with git init --bare. On our clients we add the git repo with git remote add production [email protected]:/var/www/forwardmx/git.

Now so far this is a pretty normal setup. The magic happens when we look at our git hook. In /var/www/forwardmx/git/hooks we create a file called post-receive. This will be triggered after a new commit was pushed. We need to make it runnable with chmod +x hooks/post-receive. And in our case include the following content into this file:

git --work-tree=/var/www/forwardmx/code --git-dir=/var/www/forwardmx/git checkout -f

source /usr/local/rvm/scripts/rvm
cd /var/www/forwardmx/code && bundle install && RAILS_ENV=production bundle exec rake db:migrate && RAILS_ENV=production bundle exec rake assets:precompile && passenger-config restart-app .

What we do here is:

  • The first line copies the checkin code to our code directory
  • The third line sources RVM to make Ruby available (only necessary if you use RVM)
  • The 4th line does a lot, first we cd into the Rails directory then we run bundle install to update gems, run a db:migrate to migrate database changes, assets:precompile to compile assets (JS & CSS) changes and in the end we restart the application with phusion passengers restart command.

Obviously the first push needs some manual work. Namely db:create but every update from there on is super simple to deploy.Thats it! This is our whole deploy magic. No capistrano, no other heavy third party tools. Just git, the tool we use in our workflow anyway.

Other articles