If you are a Rails-developer, and you don’t know about Heroku, now would definitely be a good time. Heroku is a platform for hosting web-based Ruby applications in “the cloud”, in this case Amazon EC2, making you able to scale your application in an effortless and cost-effective manner without worrying about the hardware behind. Heroku differs from competition by offering by far the fastest and easiest way to deploy your Rails-application. You simply create your application from Heroku’s web interface or using their API, and then push your git-repository to Heroku’s git-server. Heroku takes care of the rest, and you can get back to coding.
I use Heroku for Capistrano, once that has been setup with the right recipes and the server has been setup to corporate and serve our web application properly. But that can also take some time, especially on a brand new server.
I did miss one important feature of Capistrano when I started using Heroku: Rollback. Writing
cap deploy:rollback has saved my behind many, many times. Granted, it has often been because of bad server configuration which shouldn’t happen with Heroku, but there has also been cases of genuine bugs resulting in all pages returning errors. When we do mess up, it is really nice to have the application back up in a matter of seconds, and then being able to take you to fix the error – perhaps even do the right thing and write a failing test for that particular bug before you fix the error.
With Heroku you don’t get rollback per se, as the application always displays the
HEAD version of the
master branch in the git repository on Heroku’s servers. However, with git we have the ability to roll back to the state of every single commit ever done. It’s just not very convenient having to figure out which commit was your last one working, especially not in a situation where your application is down. Also, we need this to be automated like everything else.
The solution I came up with was to tag each release with a timestamp – just like Capistrano names its release directories. This gives me a series of tags that should all point to successful deployments, and when my hour of distress arise, I can simply tell the
master branch on Heroku to point to the previous release. If I further delete the tag of my current release, I have effectively rolled back to my previous release, and hopefully my application is now up and running again.
If you want this functionality in your Heroku application, just copy the above code into a
.rake in your
lib directory. You deploy your application with this command
rake deploy and roll back with
Please note that the script also runs migrations on each deploy, but feel free to delete that line. Suggestions and improvements are very welcome. Enjoy.
Update: Nicola Junior Vitto pointed out that my rollback code was not working correctly, and managed to fix it. His fork of the deployment script also features support for both a production and a staging environment – I’ve updated mine so rollback work, but kept it more simple without support for multiple environments.