A while back in episode 6.3 we briefly discussed deploying your Ember app using ember build -prod and placing the resulting built assets in an s3 bucket. This is a fine deploy strategy but there are other more robust options available. Probably the easiest way to deploy an Ember app is using Heroku. Heroku has all of the tools you need to get your app deployed and get your deploy fine-tuned. Today we are going to look at how we can get our app deployed to Heroku. Then we are going to deploy it with Fastboot.

We are going to start with our School Directory app that we have worked on in the past. You can find a link to the Repo in the notes. I also have a Rails app which will provide the api for our Ember app. The Rails repo is also available in the notes. To follow along, you will need to clone the Rails repo and customize it to match your Ember deploy. Let's get into it.

First, let's get our rails app running locally and hook it up with our Ember app in development before we push them to Heroku and run them in production. First, we will need to update the CORS settings for our Rails app.

From the base of the Rails app, in config/initializers/cors.rb we just need to change the origins to permit localhost:4200. We will need revisit this setting and update it with our Ember production url before we deploy our rails app. But for now, our CORS initializer will look like this:

Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'localhost:4200'

    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end

Now, back in our Ember app, let's add a host property to our application adapter. In app/adapters/application.js:

import JSONAPIAdapter from 'ember-data/adapters/json-api';

export default JSONAPIAdapter.extend({
  host: 'http://localhost:3000',
  namespace: 'api'
});

Once again, we will update this property before we deploy. One more thing we have to do to test this is to disable mirage in development so that our api calls aren't intercepted. We can do this in Ember's config/environment.js:

module.exports = function(environment) {
  var ENV = {
    modulePrefix: 'school-directory',
    environment: environment,
    baseURL: '/',
    locationType: 'auto',
    EmberENV: {
      EXTEND_PROTOTYPES: {
        Date: false,
      },
      FEATURES: {
        // Here you can enable experimental features on an ember canary build
        // e.g. 'with-controller': true
      }
    },
    'ember-cli-mirage':  {
    },

    APP: {
      // Here you can pass flags/options to your application instance
      // when it is created
    }
  };

  if (environment === 'development') {
    ENV['ember-cli-mirage'].enabled = false;
    // ENV.APP.LOG_RESOLVER = true;
    // ENV.APP.LOG_ACTIVE_GENERATION = true;
    // ENV.APP.LOG_TRANSITIONS = true;
    // ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
    // ENV.APP.LOG_VIEW_LOOKUPS = true;
  }

  if (environment === 'test') {
    // Testem prefers this...
    ENV.baseURL = '/';
    ENV.locationType = 'none';

    // keep test console output quieter
    ENV.APP.LOG_ACTIVE_GENERATION = false;
    ENV.APP.LOG_VIEW_LOOKUPS = false;

    ENV.APP.rootElement = '#ember-testing';
  }

  if (environment === 'production') {

  }

  return ENV;
};

Inside our ENV variable, we will create a property called ember-cli-mirage that is just an empty object. Then, in our environment==='development' block we will set the enabled flag to false.

We should also change our link-to in the contacts template to pass the contact id rather than the contact object so that we fetch a new version of the contact with its sideloaded relationships. In app/templates/contacts.hbs just change contact to contact.id:

{{#each model as |contact|}}
  {{#link-to 'contacts.contact' contact.id class="list-group-item"}}{{contact.fullName}}{{/link-to}}
{{/each}}

Now, if we start our rails server and our ember server and open http://localhost:4200, we should see that everything works as we would expect. So, all that is left is to deploy our apps. Deploying our rails app to Heroku is super straight forward, but a bit outside of scope here, and there are plenty of resources available to help there. I'll place a link in the notes. Also, don't forget to update the origin in your Rails app's CORS initializer. Let's look at deploying our Ember app.

First, let's make our Ember App's host point to our production Rails app. Back in app/adapters/application.js change the host property to match your deployed Rails app. In our case, it is https://dailydrip-school-directory-api.herokuapp.com.

Now, let's create our Ember app on Heroku. We will call our app dailydrip-school-directory. Back in our Ember app root, assuming you have Heroku toolbelt installed and you are logged in, we can create a new heroku app and add the need buildpack by using heroku create:

Create the app and add the buildpack for Ember:

heroku create dailydrip-school-directory --buildpack https://codon-buildpacks.s3.amazonaws.com/buildpacks/heroku/emberjs.tgz

Now just push to Heroku to deploy:

git push heroku 11.2.start:master

Now if we go to our Ember app at https://dailydrip-school-directory.herokuapp.com we will see that everything is working. That is it for today. Tomorrow we will look at Fastboot. See you then.

Links