Series: ember-cli-deploy

ember-cli-deploy-Lightning Strategy Part 1-Development

Published on Jun 15, 2016

Serve Ember from your API server with the original Lighting Deploy Strategy- now made easier, both because the maintainers have created a simpler API and because you can use the knowledge you gained in the last 4 episodes.

This first part covers setting it up to work on development.


Links

Code

$ ember install ember-cli-deploy-lightning-pack
//ember-cli-build.js
module.exports = function(defaults){
  var app = new EmberApp(defaults, {
    fingerprint: {
      prepend: 'https://monster-demo.s3.amazonaws.com/',
      enabled: true
    },
  })
}
//deploy.js
var VALID_DEPLOY_TARGETS = [ //update these to match what you call your deployment targets
  'dev',
  'prod'
];

module.exports = function(deployTarget) {
  var ENV = {
    build: {},
    redis: {
      allowOverwrite: true,
      keyPrefix: 'ember-2-0-frontend:index'
    },
    s3: {
      prefix: 'ember-2-0-frontend'
    }
  };
  if (VALID_DEPLOY_TARGETS.indexOf(deployTarget) === -1) {
    throw new Error('Invalid deployTarget ' + deployTarget);
  }

  if (deployTarget === 'dev') {
    ENV.build.environment = 'development';
    ENV.redis.url = process.env.REDIS_URL || 'redis://0.0.0.0:6379/';
  }
  ENV.s3.accessKeyId = process.env.AWS_ACCESS_KEY;
  ENV.s3.secretAccessKey = process.env.AWS_SECRET_KEY;
  ENV.s3.bucket = 'monster-demo';
  ENV.s3.region = 'us-east-1';

  if (deployTarget === 'prod') {
    ENV.build.environment = 'production';

    ENV.redis.url = process.env.PROD_REDIS_URL;
  }

  return ENV;

  /* Note: a synchronous return is shown above, but ember-cli-deploy
   * does support returning a promise, in case you need to get any of
   * your configuration asynchronously. e.g.
   *
   *    var Promise = require('ember-cli/lib/ext/promise');
   *    return new Promise(function(resolve, reject){
   *      var exec = require('child_process').exec;
   *      var command = 'heroku config:get REDISTOGO_URL --app my-app-' + deployTarget;
   *      exec(command, function (error, stdout, stderr) {
   *        ENV.redis.url = stdout.replace(/\n/, '').replace(/\/\/redistogo:/, '//:');
   *        if (error) {
   *          reject(error);
   *        } else {
   *          resolve(ENV);
   *        }
   *      });
   *    });
   *
   */
}
class RootController < ApplicationController
  respond_to :html

  def index
    render text: html
  end

  def html
    $redis.get "ember-2-0-frontend:index:#{current_revision_key}"
  end

  def current_revision_key
    $redis.get "ember-2-0-frontend:index:current"
  end
end
#routes.rb
root to: 'root#index'
//gemfile
gem 'redis'
//config/initializers/redis.rb
$redis = Redis.new(url: ENV["REDIS_URL"])

Transcript

Hey and welcome back to our series on ember-cli-deploy. In this episode and the next, we’re going to be going over the ember-cli-deploy lightning strategy. So this is the strategy that was originally used to introduce ember-cli-deploy. And it’s the one that was honestly kind of hard to get started with when you’re going at it all at once. But we’ve taken four episodes to go through some of the basics, so we should be able to understand this now.

So let’s dig in a little deeper to what the lightning pack is. So it’s a plugin pack that contains a group of plugins. And you’ll recognize some of these plugins. We were previously using build, display-revisions, s3, and revision-data. Of the three new ones, manifest and gzip are really simple. You just install them and there’s no setup. The redis addon is a little bit more complicated, and we’ll get into that later in this screencast.

Here’s the architecture for the lightning deploy. So you have your server, and the original example as well as today’s example, it’s going to be a Rails server, but it can be any server you want as long as it's connected to Redis. Then you have the AWS service, and that’s set up really close to how we had it before, except instead of s3 index being used to determine which is currently active, that’s going to be taken care of by Redis on the Rails server. So you have a root page where it connects to Redis and it sees what the current active one is. Then every time you use ember-deploy, it’ll both upload things to Amazon and it’ll make changes in Redis on your server. But you don’t have to redeploy your Rails server. If this still doesn’t make complete sense to you, don’t worry, we’ll be going over it step by step.

So our first step is going to be to delete all of the addons we were using that were related to ember-cli-deploy, except of course for ember-cli-deploy itself. Those will be replaced just by the plugin pack. Then we’ll install the plugin pack. When it asks you whether to overwrite deploy.js, say yes. We’ll grab what we need from the old one from the git diff. So here’s our new deploy.js. So as you can see, we define some environment variables they have in common, and then we check to make sure that it’s a valid deploy target, and then we set up some stuff differently based on what the deploy target actually is.

So in this series, we’re just going to be doing development and production, so we’ll get rid of qa. And in this episode, we’re only going to be worrying about dev, so we’ll tackle production in the next episode.

So our big obstacle right now is the REDIS_URL. What is that and how do we set it up? So Redis is a data structure store, and we’re going to use it basically just as a key value store. So you can install it by downloading it, or if you’re on a Mac, then you can install it via Homebrew. Once it’s installed, you can start it up using redis-server. And that’ll go ahead and start a server and put it on Port 6379. Then in our server, we need to include redis, for Rails it’s including the redis gem, and then running bundle install.

Then we’ll create a Redis initializer which calls Redis.new and feeds it the url which we’re storing in the Redis_URL, which will be defined by .env. And here for development, the Redis_URL is redis://127.0.0.1, that’s the same as the local host, and then port 6379, which as you recall is what Redis is running on. So now we have Redis all set up. Let’s get to using it.

So we’ll need to create a route that is just at the base url, and in Rails we can do that with root. So we’ll root it to the root controller and then the index method. Then we’ll go ahead and generate the root controller using Rails. On the RootController we’ll make sure that it’s going to respond to html, then we’ll create the index method. And it’s just going to be rendering some text, and it’ll be rendering it from the html method which we’re going to... within the html method, we’re going to get stuff from redis. And so here is where it’s really important that you have it synced up with the Ember app.

So in the Ember app see this keyPrefix, we’re going to be using that. So we’ll be getting that keyPrefix and then it will get the current_revision_key. And that current_revision_key is also stored on redis. And that redis key will start with that keyPrefix and then current.

And so these are the patterns that are already set up in ember-cli-lightning-deploy. We just have to make sure to connect with them. And if you’re not using a Rails backend, I hope you’re still paying attention, because even though this stuff may be Rails specific, this is going to apply to your backend as well. But that’s enough about the backend for now. Let’s go ahead and get back to the frontend.

So we’re going to need to go ahead and define REDIS_URL on the frontend as well. We’re going to do it in the .env file but I don’t really want to show you that, so just know that it looks like this, the exact same as it did on the server. So yes, we’re going to be talking to the same Redis server, and it’s great.

So let’s see what happens when we deploy to dev. So we’re going to type in ember deploy dev, and it looks like it’s going to make us fix some syntax errors that are in production in this deployTarget, even though it’s not going to go through that code route. So we’ll go ahead and just comment those out for now. And now we’ll deploy.

But if you check out the deploy list for dev, you’ll see a problem, namely that there aren’t any revisions for that key, so there’s something missing. And what’s missing is that we have for some reason decided to only use certain plugins. And let’s go ahead and use all our plugins so that we can get the correct revisions. So now since we’re no longer artificially limiting the plugins that we’re using, we’ll be using the s3 plugin, and so we’ll need to have this as general purpose stuff.

You can go back in your github diff and see what your bucket region were before you created the new deploy.js file. So we’ll go ahead and set those. We’ll also make sure that other ones are using the names that we gave them before. So now when we run deploy, notice that it’s running more things and it also creates a revision for us. So if we ask for the list of deploys it’ll actually give us something. And of course we’ll have to activate the thing we just deployed.

But when we try to view it, there’s a problem. It’s trying to pull stuff from local host assets instead of from s3 where it’s stored. Our first fix will be to go to ember-cli-build and add a fingerprint option. So it’s going to prepend it with this url, our s3 bucket, and then we’re going to say enabled: true. We’ll deploy this, and then we’ll see that it’s working. So we have successfully done the ember-cli-lightning-deploy on development. Notice it is at localhost:3000 where the Rails server is being served, not 4200.

So to review, in this episode, we deployed it on development using the ember-cli-deploy lightning pack, and we went over the changes that were required both in the ember frontend as well the changes required in our Rails backend. In our next episode, we’ll show how to get this going on production, in this specific case, going on a Rails app on Heroku, but we’ll learn some things that can be applicable to any type of server. I’ll see you then.

ember-cli-deploy

Subscribe to our mailing list