2

Is it possible to follow the principle of "build once, deploy anywhere" for an angular 2 application?

I keep finding answers that tell me to just build it seperately for every environment, but that's not what I'm looking for.

We're using docker and tomcat.

Thanks in advance.

8
  • 1
    That's definitely possible, could you provide a bit more info? What do you want to change depending on the environment? Is it to have different config for each environment? Commented Jun 9, 2017 at 9:26
  • mainly URLs to the backend API. We have seperate URLs for our acceptance environment, development environment etc. So yes, a different config for each environment. Commented Jun 9, 2017 at 9:47
  • Is your angular app served by tomcat? Commented Jun 9, 2017 at 9:59
  • @Krikke93 We build some image + provide environment variables with the docker run command and this env will be the values of our configs using a bash-script in our docker container that will fill in the env vars using sed. Like the answer here: stackoverflow.com/questions/38436129/… Commented Jun 9, 2017 at 9:59
  • @lorenzvth7, does this work for Angular 2? Because first thing I notice is that the person in question is using AngularJS instead of Angular 2. Commented Jun 9, 2017 at 10:49

1 Answer 1

2

I think a common point of all app to load config dynamicaly is to use the angular provider called APP_INITIALIZER.

This provider allows to execute some code before bootstrapping angular app. Typically the code to execute is something like get some config from an endpoint, eg /configuration. Example here

You can write the code yourself or you can use this lib (under the hood this uses the APP_INITIALIZER): https://github.com/ngx-config/core, more precisely the ConfigHttpLoader

In the example below, we use the lib to load /configuration through an http call. This goes in your app.module.ts

export function configFactory(http: Http): ConfigLoader {
  return new ConfigHttpLoader(http, '/configuration'); // FILE PATH || API ENDPOINT
}    

@NgModule({
imports: [
ConfigModule.forRoot({
          provide: ConfigLoader,
          useFactory: (configFactory),
          deps: [Http]
        })
]
})

Then, the way you provide /configuration depends on how you serve your app. What I did in a project was :

  • frontend app is packaged with all configurations (dev.json, integ.json, prod.json)
  • pass to docker an environment variable (dev or integ or prod)
  • in the Dockerfile of the docker image, make a symlink to the correct config file, depending on the environment, then start the server (in my case it was nginx) :

CMD ln -nfs /path/to/config/${ENVIRONMENT}.json /path/to/configuration && nginx -g "daemon off;"

This way your frontend app always load /configuration, but depending on the environment, the symlink will point to a different config file.

You could use something like this.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.