DevGang
Авторизоваться

Angular в Docker - настройки среды 

У приложений Angular часто есть параметры, которые различаются в зависимости от среды, в которой они работают. Например, при запуске приложения в рабочей среде приложению может потребоваться использовать другой URL-адрес для подключения к серверному API, по сравнению с промежуточной средой или локально на машина разработчика.

Одним из решений является помещение настроек в файл environment.ts и добавление дополнительной среды. {Env-name}.ts файлов для каждой среды, которая нам нужна. Это означает, что нам нужно указать среду при создании нашего приложения, что не очень хорошо, когда мы хотим развернуть образ.

Когда приложение Angular развертывается как образ Docker, мы действительно хотим, чтобы один и тот же образ использовался независимо от среды, в которой мы развертываем, поэтому необходимо другое решение.

Во-первых, нам нужно поместить параметры, необходимые для локальной разработки, в файл json. Я поместил этот файл в папку assets, которая копируется в папку dist при сборке проекта (при условии, что вы используете angular cli).

settings.json
{
    "apiUrl": "http://localhost:5000"    
}

Затем мы создаем класс для представления настроек в нашем приложении Angular:

settings.ts
export class Settings {
    apiUrl: string;   
}

сервис, который можно внедрить в любой класс, которому нужен доступ к настройкам:

settings.service.ts
import { Settings } from './settings';
import { Injectable } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class SettingsService {
    public settings: Settings;

    constructor() {
        this.settings = new Settings();
    }
}

и другой сервис для запроса настроек при запуске приложения:

settings.http.service.ts
import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { SettingsService } from "./settings.service";
import { Settings } from "./settings";

@Injectable({ providedIn: 'root' })
export class SettingsHttpService {

    constructor(private http: HttpClient, private settingsService: SettingsService) {
    }

    initializeApp(): Promise {

        return new Promise(
            (resolve) => {
                this.http.get('assets/settings.json')
                    .toPromise()
                    .then(response => {
                            this.settingsService.settings = response;
                            resolve();
                        }
                    )
            }
        );
    }    
}

Эта служба должна быть зарегистрирована как APP_INITIALIZER в app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, APP_INITIALIZER } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import { SettingsHttpService } from './settings/settings.http.service';

export function app_Init(settingsHttpService: SettingsHttpService) {
  return () => settingsHttpService.initializeApp();
}

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule
  ],
  providers: [
    { provide: APP_INITIALIZER, useFactory: app_Init, deps: [SettingsHttpService], multi: true }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

После этого приложение должно загрузить настройки, указанные в файле settings.json, при запуске.

Чтобы изменить настройки в зависимости от среды, я добавляю дополнительный файл в папку assets.

settings.template.json
{
    "apiUrl": "${API_URL}"  
}

Он имеет ту же структуру, что и файл settings.json, но вместо значения параметра указывает имя переменной среды.

Затем я изменяю свой Dockerfile, чтобы при запуске контейнера он заменял имена переменных среды в файле шаблона на значения этих переменных и перезаписывал файл settings.json с результатом до запуска веб-сервера.

FROM node:latest as builder
WORKDIR /usr/src/
RUN git clone https://repo/myproject
WORKDIR /usr/src/myproject/web
RUN yarn
ENV PATH /usr/src/myproject/web/node_modules/.bin:$PATH
RUN yarn buildProd

FROM nginx

COPY --from=builder /usr/src/myproject/web/dist/web/ /usr/share/nginx/html

CMD ["/bin/sh",  "-c",  "envsubst < /usr/share/nginx/html/assets/settings.template.json > /usr/share/nginx/html/assets/settings.json && exec nginx -g 'daemon off;'"]

В этом случае я использую стандартный образ nginx - если вы используете что-то другое, вам нужно внести соответствующие изменения.

Я использую envsubst для выполнения подстановки переменных, а затем запускаю nginx.

Теперь, когда я запускаю контейнер, я могу передать свои настройки в качестве переменных среды.

Таким образом, теперь один образ можно развернуть в любом количестве сред, и настройки изменились соответственно.

Источник:

#Angular #Docker
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу