Articles

Deploying to Multiple Server Environments in Ember

4 min read

Ember CLI allows you to build your Ember application for different environments by passing a --environment option to the ember build command. For example, if we wanted to build for a production environment we would run the command ember build --environment production.

We can then configure our environment variables in config/environment.js. If we wanted to configure an API endpoint for different environments, we could do the following:

import "./styles.css";

document.getElementById("app").innerHTML = `
<h1>Hello World</h1>
<div>
  We use the same configuration as Parcel to bundle this sandbox, you can find more
  info about Parcel 
  <a href="https://parceljs.org" target="_blank" rel="noopener noreferrer">here</a>.
</div>
`;

This works great for applications that only deploy to one server. But what if we wanted to deploy to a staging server? You might think that you can do this:

import "./styles.css";

document.getElementById("app").innerHTML = `
<h1>Hello World</h1>
<div>
  We use the same configuration as Parcel to bundle this sandbox, you can find more
  info about Parcel 
  <a href="https://parceljs.org" target="_blank" rel="noopener noreferrer">here</a>.
</div>
`;

This will deceivingly work, but it's bad practice. This is because Ember actually ships with only three build environments:

  1. test
  2. development
  3. production

When one of these environments aren't passed as the --environment option, Ember CLI defaults to the development environment but will still run the logic for the passed environment in config/environments.js. So, in the example above, the API endpoint will correctly be set to https://staging.myserver.com/api, but the application will be built as a development environment. This means that we lose important benefits of building as a production environment such as minifying and fingerprinting files.

The problem is that the example code above conflates the Ember build environment with the deployment environment. This is fine if you have one production environment but becomes a problem when you want to deploy to multiple environments. So what are we supposed to do? The solution is to use the popular community addon ember-cli-deploy.

ember-cli-deploy allows us to separate the build environment from the deployment environment by exposing an ember deploy command. You can install the addon by running ember install ember-cli-deploy. After installation, a config/deploy.js file will automatically be created with the following content:

import "./styles.css";

document.getElementById("app").innerHTML = `
<h1>Hello World</h1>
<div>
  We use the same configuration as Parcel to bundle this sandbox, you can find more
  info about Parcel 
  <a href="https://parceljs.org" target="_blank" rel="noopener noreferrer">here</a>.
</div>
`;

As you can see, we now have access to a deployTarget variable separate from the build environment. We provide this variable by passing it to the ember deploy command. So, for example, if we wanted to deploy to our staging environment we would run ember deploy staging.

And that's it! I know that the difference between build and deploy environments was not entirely obvious to me when I first started deploying Ember applications so hopefully this helped to eliminate some confusion. And, now that you have ember-cli-deploy installed, I would highly suggest looking at the other capabilities of the addon. It has a rich plugin ecosystem that can help you with tasks like gzipping, uploading to S3, sending deploy notifications, and more.

© Matt Beiswenger 2023Built with Next.js, deployed on ▲Vercel