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:
#!/bin/bash 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
cdinto the Rails directory then we run
bundle installto update gems, run a
db:migrateto migrate database changes,
assets:precompileto 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.