Running Ember Fastboot on Your Custom Server Machine with ember-cli-deploy and S3
Ember-fastboot is a server-side rendering mechanism for the Ember.js framework. It’s almost ready for release, with some minor bugs in Github issues, but there is already a release candidate for 1.0.0.
We haven't used fastboot in production until recently, so we needed to build a deployment pipeline from scratch. The open-source community is absolutely amazing with all the blocks available. All you need to do is to connect the blocks properly – check out how.
P.S. If you just want to see the code examples, go directly to this repository and have a look at the minimal configuration.
What are we going to build?
Below you will find a sketch of what our final deployment pipeline should look like:
We will go through the pipeline step by step to help you understand what is going on there specifically.
How does it work?
First, we need to have an environment in which we will build our Ember application with the production target. This might be your development environment or a Continuous Integration environment. Bear in mind, though, that it shouldn’t be your production environment – we need to have all
package.json, and they won’t be installed in the production environment where
NODE_ENV should be set to production.
ember-cli-deploy pipeline consists of three steps. First, we built the app. We use ember-cli 2.12, which means that the build step, performed by
ember-cli-deploy-build, already includes by default all fastboot-related work we need. Next, we use
ember-cli-deploy-revision-data to have a unique revision key for our build. Finally, we use
ember-cli-deploy-fastboot-s3, which is responsible for zipping our dist folder and uploading it to our S3 bucket. If we also activate this revision, the pipeline will create a
fastboot-deploy-info.json file, containing the bucket name and the filename of the active revision. The pipeline will upload it to the same bucket that it has just uploaded our zipped dist directory to.
A fastboot server should not change as often as the frontend. It is recommended that you restart it only if necessary. I’m not going to cover how to deploy the repository to your server in an automated way, because it would be very specific to your particular setup. At Netguru, we use Capistrano and the capose gem to run a docker container with the repository fetched and node already installed.
fastboot-app-server is an open-source production-ready node server that is able to serve a built Ember app distribution. It is, as everything in the Ember community, very easy to use and run. We will talk about the configuration later, so let’s discuss what it is responsible for. We use it with fastboot-s3-downloader, and thus we can use the builds from ember-cli-deploy directly from S3. First, it checks if it can serve any application. If no, it tries to download a new one from S3. The pipeline is as follows:
Connect to S3 and download
fastboot-deploy-info.jsonget info about which revision is active.
Download active revision.
Install fastboot-dependencies by running
npm install --productionin the revision’s unzipped directory.
Serve this unzipped build.
fastboot-s3-notifier is a package that polls your S3 bucket every 3 seconds and checks the last_modifed field in
fastboot-deploy-info.json. As soon as it changes, the fastboot server will download the new active revision and serve the new one, without even restarting itself. This is why a fastboot server does not have to be redeployed frequently – it can handle new frontend builds automatically.
In order to set fastboot, we add ember-cli-fastboot first. We need to make sure that we set
ember-cli-build.js to true in production. Without this, our fastboot server will not be able to serve fingerprinted assets.
Then, we add
fastboot-s3-downloader, used later, connects to AWS by API v2, which is not supported in all AWS regions. AWS Virginia (us-east-1) supports this version, so I recommend that you use this server.
Let’s deploy our app with the following command.
$ S3_BUCKET=... S3_ACCESS_ID=... S3_ACCESS_KEY=... S3_REGION=... ember deploy production
Let’s do a checkpoint here and make sure that there are two files in your S3 bucket:
fastboot-deploy-info.json and a fingerprinted dist zip.
Now, we need to install
fastboot-app-server with S3 notifier and downloader.
Important information: the aws-sdk package, used internally by S3 downloader, needs to have either an aws profile configured on the machine or proper AWS environment variables set up. That’s why you should set the following environment variables in your environment:
First, let’s see if we can run our fastboot server locally using the already deployed dist zip. Run the following command with the environment variables mentioned above and S3_BUCKET set in your environment:
$ S3_BUCKET=... AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... AWS_REGION=... node fastboot-server.js
You should be able to access your production-env-served Fastboot app on http://localhost:3000!
The last step will be to start your fastboot server (the same thing we did in the previous step) on your real production machine. This is not part of this tutorial, as this is rather a node-server deployment not specific to ember fastboot. The easiest thing would be to git-clone it, run
npm install --production, set up your AWS-related environment variables (mentioned above) and run
fastboot-server.js. Ping me on Twitter if you have any problems with this!
You have learnt how to setup an ember-fastboot-based application with an ember-cli-deploy pipeline based on S3. This is one of the most robust deploy processes in my opinion. If you use a different process, give me a shout on Twitter – I would love to hear about it!