Deploy Ember to S3 and CloudFront

elbuo
2 min readMay 20, 2015

--

I’ve yet to write a single line of Ember for production code but I still had to figure out deployment for it. Luckily, there are some awesome tools out there. I’ll try to explain how we setup S3 to serve our Ember application, setting up CloudFront, and how we automated that in our deployment process.

The first thing that we wanted to accomplish was the elimination of server(s) maintenance/scaling. Regardless if it was a framework or just nginx serving the assets. We just wanted the feeling we had back when we just uploaded assets through FTP and everything worked (those days are long gone).

Secondly, we wanted to keep using our same tools and development workflow. Deployment using our favorite command:

$ git push

To tackle our asset hosting, we decided to stick with S3. This part was pretty simple. First, create a bucket and enable “Static Website Hosting”. For the index document, make sure you point it to your Ember app’s index file. Now, your “redirection rules” should look similar to this. Remember to replace with your own domain name.

Now, how do we deploy with just 1 command? That’s where ember-deploy comes in to save the day. It hooks in into our ember-cli workflow and makes deployments a breeze. The “lighting approach” uses redis to map the index file. We opted to do a simpler approach. First:

$ npm i ember-cli-deploy ember-deploy-s3 --save-dev

Create a deploy.js file inside a config folder. Similar to this one:

Now simply run

$ ember deploy -environment production

And all of your assets will be uploaded to your bucket and accesible through the “Static Website Hosting” URL provided.

Now, lets take it a step further. Lets throw this behind CloudFront. Create a distribution, where the origin is the url provided in the “Static Website Hosting”. I emphasize this given that the CF UI will start autocompleting for you and you will end up setting the origin as the bucket name. That is not what we want. We want the URL.

Point your domain to your CF distribution and behold your Ember app.

Lets tackle our continuos deployment using git. In our CI we have the following commands after our test suite finishes successfully.

$ ember deploy -e production
$ pip install awscli
$ aws configure set preview.cloudfront true
$ aws cloudfront create-invalidation --distribution-id DISTRIBUTIONID --invalidation-batch "{\"CallerReference\": \"$(cat /proc/sys/kernel/random/uuid)\", \"Paths\":{\"Quantity\":1,\"Items\":[\"/index.html\"]}}"

Breaking it down, the commands do the following:

  1. Deploy the latest version of the app (we use fingerprinting for our assets).
  2. Invalidate the index.html in our CF distribution.

This will cause that the next time we visit our app (after the invalidation) we will be served the updated index.html that will point to the latest assets.

This is, by no means, our last iteration of deployments. There is a lot of room to improve, specifically when it comes to the invalidation part. But, I figured that someone could use this as a starter (I know I could have used it myself). Always glad to discuss optimizations. Enjoy.

--

--