A couple of months ago I wrote an article about deploying ember-cli apps to heroku. Looking back, it was more a dirty hack to get things working than a long term solution.
During Ember Conf I had the opportunity to talk with some of the @yapplabs folks about the method they were using to deploy their apps and then Luke Melia gave an interesting talk on Rails Conf  about it.
Then, there was a blog post by Feifan Wang  implementing Luke’s concepts, and I used that as the backbone for my current solution.
Instead of prefixing the current deploy with timestamps, we put all the files on the same dir to avoid cache busting. By default when accessing the app in Rails, we’ll serve serve the latest stable release which is stored in Redis as “release:index.html”, or if the user asks for the “canary” version (?version=canary) then serve the latest known deployment.
The reason for including a ‘canary’ release  is that I can test stuff in production before making it available to the public, also being able to serve other versions, means we can develop different features and share the same “staging” app, and then just test by passing as param the feature’s shortSHA.
There are more advantages about this approach, check out Luke’s video for more enlightment!
Generating the build.
First let’s examine the Brocfile, we just tell Broccoli to fingerprint our assets preprending our cloudfront url to all of them.
the final result would look something like
1 2 3 4 5 6 7 8 9 10 11 12 13 14
With that we get our desired ‘dist’ output. Next we need to upload it to S3 (we might be able to do this directly with ember-cli soon)
Next we tell grunt to upload to S3 and push the generated index to
Redis. The default task publish the index as a canary release (meaning
it doesn’t get served by default) just if the user explicitly requires
?version=canary. If we want to make the current version the
one that the users get served then we run
Normally we’ll run the default task on our CI server against staging, and then when things get merged into production run the release task, optionally we can run always the default task against production, in that way your clients can try the latest version of the app before making it available to everyone else.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
In rails we will need to have
redis gem installed and then
in our root action just serve the index.html from Redis.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
And voilá! You have separated your Ember.js and Rails app with super fast deployments!
Dealing with CSRF can be done injecting the csrf token in your header and then telling Ember to pick it up for you, or use my rails-csrf plugin which will take care of everything, it just requires and end-point for fetching the csrf token.
Standing on the shoulder of giants.
Thanks Luke, for your Rails Conf talk!
Thanks Feifan Wang for you blog post and
Pair with me.
If you are looking for help with Ember.js/ember-cli/Rails, I do a free hour of pairing every week, shoot me an email to email@example.com.