Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular & Docker: Environment aware configuration

Tags:

docker

angular

We'recurrently setting up an SPA with Angular 4, hosting it with Docker on Azure. Usually, the environments (Prod, Development, Testing) are set in Angular with the Environment-Configs, which are compiled, if we use the Angular-CLI build command. This is great, but the workflow with Docker is a bit different:

  1. Build the Angular App
  2. Initialize the Docker container
  3. Set the Docker Container environment variables
  4. Start the Docker container

This means we have a timing problem, because on compile-time, we can't say, on which environment the App will run. For the server (.net core), this is no problem, since we can use the ASPNETCORE_ENVIRONMENT variable, but we didn't find a solution to make the App aware of the environment-type. I'm almost certain we're not the only people around with this problem, yet I didn't find proper solution so far. Is there some possibility around we aren't aware of?

like image 636
Matthias Müller Avatar asked Jun 14 '17 15:06

Matthias Müller


People also ask

What is Angular used for?

Angular is a platform and framework for building single-page client applications using HTML and TypeScript. Angular is written in TypeScript. It implements core and optional functionality as a set of TypeScript libraries that you import into your applications.

Is Angular JavaScript or Java?

Angular JS is an open source JavaScript framework that is used to build web applications. It can be freely used, changed and shared by anyone.

Is Angular front end or backend?

AngularJS: AngularJs is a JavaScript open-source front-end framework that is mainly used to develop single-page web applications(SPAs). It is a continuously growing and expanding framework which provides better ways for developing web applications.

Is Angular hard to learn?

The answer to the question- Is angular easy to learn, totally depends on your knowledge and learning of JavaScript. So if you have a basic knowledge of JavaScript, it would be easy for you to sail through. But are not well versed with your basics then indeed learning Angular will be an uneven hilly patch for you.


1 Answers

Since my main goal was to not create a Container per environment but also to keep the build process environment-agnostic, I came up with the following solution: I'm using the docker-stack file to add a command (My Docker image is NGinx):

command: /bin/bash -c "cp /usr/share/nginx/html/assets/app-settings/appsettings.__EnvironmentName__.json /usr/share/nginx/html/assets/app-settings/appsettings.json && find "/usr/share/nginx/html/assets/app-settings/" -type f -name "*.json" -not -name "appsettings.json" -exec rm {} ';' && exec nginx -g 'daemon off;'"

The command does three things:

  1. Copy a environment specific appsettings.json (see below) as appsettings.json
  2. Remove all appsettings.xxx.json except appsettings.json
  3. Start nginx

The release process also replaces EnvironmentName with the specific environment it is deploying to. This means, each container has now an appsettings.json in place with the environment-specific data. On the angular code, I'm using the environment-files just for compile-time, environment-agnostic, information:

export const environment = { production: false };

The appsettings are saved as assets:

enter image description here

To read the runtime information of appsettings.json, I've created a appsettings provider service, using a local http call:

@Injectable()
export class AppSettingsProviderService {
  private appSettings: AppSettings;

  public constructor(private http: LocalHttpService) {
  }

  public async provideAppSettingsAsync(): Promise<AppSettings> {
    if (this.appSettings) {
      return Promise.resolve(this.appSettings);
    }

    // This path needs to be relative to the files in the dist-folder
    this.appSettings = await this.http.getAsync<AppSettings>('./assets/app-settings/appsettings.json');
    return this.appSettings;
  }
}

This works also during development, since just the appsettings.json is used in this case and even with ng serve, the code is compiled into dist, meaning the relative path is still correct.

like image 129
Matthias Müller Avatar answered Sep 18 '22 23:09

Matthias Müller