First impressions deploying to Heroku
My new place is moving from being a startup to having to put in places some things you need for the longer term running of a charity. So, I've been fiddling with a few apps. I'd deployed one which works perfectly in dev and test and one of my staff, when I said i was about to spin up an EC2 instance to host it, mentioned it was small enough we could run probably run it for free on the everyone-gushes-about-it Heroku (which is something I've thought about some of my other personal apps).
He was right (of course) so I set about grabbing the heroku gem and did a quick once over on the documentation. The app was a fairly simple thing I threw together for an internal issue we have.
So, first off... Yeah, Heroku is dead easy. App create and app pushing from git is a dream. I have to admit, a git push, the spin up on the slug and the fact it was there and running were all a testimony to some very, very clever design and well thought out decisions in terms of making deployment painless.
Add-Ons are mind-blowingly great. Want custom domain configged ? Check! Monitoring, Exception and Performance checking? Check! Post deploy email notification? Check! Oh email send outs? Check! Cron set up? Check! And you can do it from the command line on top of that or the very slick web interface.
So, really this post is more about niggles than anything substantive since there is a part of me that felt deployment was a bit less than painless because of the things I didn't know about Heroku. I'd also suggest Heroku needs something like a Rails scrubber to check those parts of your code which would work on a traditional server but won't work on Heroku because of the differences that have been necessary there to make it work so flawlessly. Cause generally, if something works on my dev flawlessly, passes all tests and then flames out on Heroku when I spin it up, I personally find causes pain.
So, just some things I noticed that made it not so painless for me. And before anyone thinks I'm slamming Heroku, I'm not. I'm definitely, definitely impressed. This post is in the spirit of making Heroku better because, to be quite honest, I think they may have a knock-it-out-of-the-park winner here with a few tweaks and people becoming more familiar and comfortable with it as a service. And let me tell you how huge a fan of capistrano and having root access to my servers I am. In fact, Heroku's caught my attention enough that I'm rethinking whether it might work for our new campaigning platform here at the ranch.
- First minor kvetch: Why on earth do you need to use a gem bundler or a .gems manifest (I used the latter)? Surely, with all the gems properly laid out in my
config.gem, Heroku should just scan this and it should just work.
- My second app blow up came when the front page wouldn't load. Again, no really good error messages until I went to look at the logs (I do like
heroku logsthough) and it identified the line with the problem. Turns out Heroku has a read-only file system so you can't do page caching and I had conflated the four stylesheets I had into one base stylesheet via the
:cachesymbol (who wouldn't ? It speeds things up.). Removing that let me see the home page.
- Surprisingly, a minor glitch with the SendGrid add-on caused quite a bit of time for me. Running
heroku rake db:seedkept throwing errors apparently because it couldn't connect to a mail server, but kept giving me the cryptic error
Connection refusedwhich made me think there was a problem with the database connection (Anyone know how to suppress a mail out for seed creation when you're creating objects for a model with an observer on them?) Anyhow, I used
heroku rake db:pushvia the taps gem in order to get round that, which was good, but felt a bit hack-y.
- Normally, in my capistrano
deploy.rbfile I place a file of the latest git revision to be in the footer for bug reporting and just general "what did I put up there?" kinda review. Doing this on heroku is a bit tricky I gather. I installed a
gritgem, and then used it in the application helper to reference my .git directory, created a
last_commitmethod and then reference these in a partial in the layout. Kaboom. Turns out accessing a git repo is expressly forbidden, so removed the git revision. Minor, but annoying. Anyone got a workaround ?
- Another minor kvetch is about how you access
cron. OK, now this makes sense but doesn't mean I can't be crotchedy about it (in fact, it's a good solution considering, but they should have a - "how you may need to change your app" kinda thing). So, normally, I use javan's fantastic whenever gem (which is the bomb) through the
cap deployto have fantastic control of cron. Heroku only let's you run crons daily (or, for a little extra, hourly) which means you need to add a cron.rake file with a rake cron task to your system which gets triggered via time checks. OK, fine, not so bad, but it's not obvious and extra code you need just for Heroku. Fair enough though.
- The last very minor issue was the fact I had a problem when I installed Sendgrid as an add-on as I mentioned above. For some reason, it didn't take and I couldn't figure out why I was getting an auth error. Turns out it is automagically configured (bless you, heroku), but some weird glitch they've got going on means some accounts don't work right away. You need to remove the add-on and add it back in again as per this post in the heroku google group and everything works aces. Special thanks to user hone in the IRC
#herokugroup who pointed me at that (you rock, sir). So, this is not really a problem though it did make me waste an hour thinking it was something I'd done wrong.
Overall though, I have to admit I am very,very impressed. The app is sitting there and running quite snappily (varnish, I assume?) and considering it's the first time I've ever used heroku, I'm astonished. Using EC2 had an obviously much higher learning curve just to get the server set up to eventually deploy to.
It's definitely got me thinking that I need to run some cost estimates on Heroku as an infrastructure competitor for the new platform (especially if we could somehow scale background workers and dynos automagically for when we do campaign send outs and actions. Hmmmm.... ).