Angular和Docker:环境感知配置

16

我们目前正在使用Angular 4建立SPA,并使用Docker在Azure上进行托管。通常,环境(生产、开发、测试)是使用Angular的Environment-Configs设置的,如果我们使用Angular-CLI构建命令进行编译,则会进行编译。这很好,但是与Docker一起使用的工作流略有不同:

  1. 构建Angular应用程序
  2. 初始化Docker容器
  3. 设置Docker容器环境变量
  4. 启动Docker容器

这意味着我们有一个时序问题,因为在编译时,我们不能确定应用程序将在哪个环境中运行。对于服务器(.net core),这不是问题,因为我们可以使用ASPNETCORE_ENVIRONMENT变量,但我们没有找到解决方案使应用程序意识到环境类型。 我几乎可以确定我们不是唯一遇到这个问题的人,但迄今为止我没有找到合适的解决方案。我们是否有一些不知道的可能性?


2
不幸的是,我们仍然没有合适的解决方案。我们创建了一个基础设施服务,它保存这些值并根据环境进行交付,但在客户端方面,似乎没有现成的解决方案。 - Matthias Müller
1
@MatthiasMüller,这可能有所帮助https://dev59.com/DFgQ5IYBdhLWcg3wJgmO#43980985 - Mehrad Sadegh
1
@MehradSadegh 这意味着我需要为每个阶段更改环境,是这样吗?我认为现在的通常目标是在多个阶段测试一个工件,而无需在之间进行修改,或者我错了吗? - Matthias Müller
1
@MatthiasMüller,我想知道你最终是如何解决的? - stevo
1
@SwissCoder 谢谢,我们也在使用AppInitializers,如果服务需要配置文件,(我想)。我仍然感到困惑,为什么没有直接支持这个,因为使用相同的构件来处理所有阶段是发布管理的主要原则之一。 - Matthias Müller
显示剩余4条评论
1个回答

7

由于我的主要目标是不为每个环境创建一个容器,同时保持构建过程与环境无关,因此我想出了以下解决方案: 我使用docker-stack文件添加命令(我的Docker镜像是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;'"

该命令执行三个操作:
  1. 将特定环境的appsettings.json(参见下文)复制为appsettings.json
  2. 删除除appsettings.json以外的所有appsettings.xxx.json文件
  3. 启动nginx
发布过程还会将EnvironmentName替换为要部署到的具体环境。这意味着,每个容器现在都有了一个放置特定环境数据的appsettings.json。
在Angular代码中,我只是将环境文件用于编译时、与环境无关的信息: export const environment = { production: false }; appsettings被保存为资源文件: enter image description here 为了读取appsettings.json的运行时信息,我创建了一个appsettings提供程序服务,使用本地http调用:
@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;
  }
}

这也适用于开发过程中,因为在这种情况下只使用appsettings.json文件,在使用ng serve时,代码会被编译到dist目录下,这意味着相对路径仍然是正确的。


2
总的来说,感谢你的帮助,Matthias!我只是稍微简化了你的解决方案,并更改了docker-compose文件以复制所需的配置到appconfig.production.json文件中。例如--> command: sh -c "cp /usr/share/nginx/html/assets/appconfig.staging.json /usr/share/nginx/html/assets/appconfig.production.json && exec nginx -g 'daemon off;'",因为我们在每个文件中都有不同的配置。这个方法完美地解决了问题! - Brian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接