How to just build for an environment other than production

As Ember CLI docs say: " Ember apps can be built with only three environments: development, production, and testing."

The question I have is:

  • is it possible to just build an app for another environment taking into account variables and secrets by environment without using ember-cli-deploy add-on ?

I previously used ember-cli-deploy and deployed to AWS S3 from my terminal without problems. The request from DevOps folks is to build the same app and then just transfer dist folder to AWS S3.

Any ideas ? Thank you.

There are only those three environments. There aren’t any others to build for.

If you want to build with different config, you can use environment variables to do that

Thank you, @alexspeller, for the response. When you say

If you want to build with different config, you can use environment variables to do that

do you mean the one of available environment variables (testing, development and production) to use when executing ember build --environment={testing or development or production}?

Ember’s environments have three settings:

  1. test for running tests
  2. development for local development, it has better error messages to help debugging
  3. production for things you want to deploy

If you’re going to deploy to a server, you want production.

To have different config, use environment variables and read their value in config.js with process.env.WHATEVER_VARIABLE

I think, there is a typo in your response, config.js shouldn’t it be environment.js? Another point, is suppose that I have the following setings in environment.js:

...
if (environment === 'staging') {
    ENV.clientID = process.env.OAUTH_CLIENT_ID;
    ENV.oauthUrl = process.env.OAUTH_URL;
    ENV.client_secret = process.env.OAUTH_CLIENT_SECRET;
    ENV.apiHost = process.env.API_HOST;
}

This will never work when running ember build --environment=staging because ember-cli does know about staging environment as there are only testing, development and production. Right ?

Technically you can define other environments like staging but it’s not recommended as Ember itself only recognizes the three (test, development, production). So what you posted above will probably ā€œworkā€, but you have to be very conscious of how ember is treating the build beyond just setting up those five variables. Likely it’s defaulting build settings to development which isn’t necessarily what you want. It’s better to do as @alexspeller mentioned and use the three basic environment settings and then set system environment variables and read from those for things that need to be customized.

@dknutsen, OK, got it. Personally, I’d prefer using ember-cli-deploy as it is more flexible and makes it possible to manage the variables by environment in separate files (env.deploy.staging, env.deloy.production, etc.) as well as to have a default ones defined in .env file. I’m not really a big fan of defining all the used variables (api host, secrets, etc.) on a system level. Thank you guys for your responses !

You can still do that without ember-cli-deploy by using an npm package like dotenv or something. In fact you can probably look at the code that ember-cli-deploy uses to read those files and more or less do the same thing, just do it in your config/environment.js file. I’ve used dotenv lib in the past to do something like this for managing variables in development and production.

@dknutsen yeah, me too before learning e-c-deploy :slight_smile: Nevertheless, even with ember-cli-dotenv, I don’t think it to be possible to build an Ember app for an environment other than one of 3 existing ones in ember-cli. What it does, if I’m not mistaken, it just provides a way to keep variables like figaro gem in Rails world in separate files and keep them away from being committed. Anyway, the guard clause in environment.js file of an Ember app just checks for one of the 3 possible environments and I can’t see how, for example, it is possible (if it is) to trigger a build for staging with ember build --environment=production and pull the corresponding variables from whatever tool you use. That’s the question. I’m of course aware that this is not a traditional way to go and that’s why I’m just searching for arguments to avoid doing that :slight_smile:

Yeah you’d have to do something more like TARGET=staging2 ember build -e production

and then in config/environment.js you could say:

if(process.env.TARGET === 'staging1') {
  // staging one setup here
}

if(process.env.TARGET === 'staging2') {
  // staging two setup here
}

Obviously you still have to choose which ember environment you want to build also, but think of that more like choosing whether or not you want minification, sourcemaps, fingerprinting, etc. or not, and then your environment variables set up specifics.

Anyway, plenty of ways to go about it, it’s just easier to avoid weird build issues if you let ember build how it is meant to and you configure your build targets using environment variables.

1 Like

Ah, OK, - I didn’t know that we could pass in environment variables like that (looks like a Rails way) by prefixing the main command to be executed. I’ll take a try and see how it goes by always building a production-like build but passing in different variables as you suggested. Thanks a lot !

The --environment argument to ember-cli is ambiguously named. Think of it instead as ā€œmodeā€. The only modes are ā€œI’m doing developmentā€, ā€œI’m running testsā€, and ā€œI’m being served to usersā€.

You might have many server environments with different settings, but they are all still ā€œin server modeā€, so they all use ember-cli’s --environment=production.

I agree that ember-cli-deploy is a good choice for managing the difference between multiple targets.

1 Like

Thanks a lot, Edward, now it is absolutely clear for me.

We had a number of apps set up with a ā€œstagingā€ environment, but we recently started using the ā€œproductionā€ environment instead (with a ā€œstagingā€ target for ember-cli-deploy).

Having 100% consistency between our staging and production environments is critical, as we actually shipped a bug that had to do with how minification ran differently between the environments. We even had minification manually turned on in our config, but there’s a number of addons and code paths that hard code a check for environment === 'production'.

Is this a valid command? because i am getting ā€œnot recognizedā€ while testing this out. ember-cli: 3.10.1 node: 12.13.1

TARGET=staging2 ember build -e production

ā€˜TARGET’ is not recognized as an internal or external command, operable program or batch file.

It’s valid for Unix based systems, if you’re running Windows try something like this?

set TARGET=staging2 && ember build -e production

I’m not 100% sure that will work as I don’t have a windows box to test on but if not I think it’s pretty close, you basically just want to temporarily set the environment variable before running the command

gotcha thanks .

I was thinking that is a nifty way of passing in a variable in cli.