Azure Slot部署的Angular 2配置问题

时间:2017-03-09 10:48:38

标签: angular azure-web-sites azure-deployment-slots

我遇到了Angular环境变量和Azure插槽的问题

我们希望使用提供静态Angular文件的应用服务,并且我们还希望使用Azure插槽来使我们的部署更安全。

我们想要使用插槽的原因是:

  1. 确保代码在生产环境中有效,然后才能让所有人都可以使用
  2. 将停机时间减少到几乎为零,因为在" go-live"相
  3. 我们的Angular站点仅提供静态文件意味着插槽部署需要不同的构建,以便为每个插槽不同地填充env.json环境设置。

    我们考虑采用的解决方案是在同一个Angular网站中创建一个端点,并从Angular站点调用回到其原点以获取其配置。这样,可以在Azure中的暂存和生产槽中以不同方式设置配置,并且只需要一个Angular构建。

    我们需要一些服务器端代码来获取这些Azure应用程序设置,并将它们提供回站点上的端点。我们还没有决定我们用来创建该端点的技术 - 我们现在正在考虑.Net Core或NodeJs,因为它们似乎与Angular产品和开发团队非常吻合。

    有没有人有任何插入服务器端组件的经验,为以前的静态Angular网站提供配置?

3 个答案:

答案 0 :(得分:1)

要实现您的要求,您只需将以下PHP文件放入站点根文件夹即可。然后通过Angular应用程序向端点http://<websitename>.azurewebsites.net/appSettings.php发送GET请求。这将为您提供一个包含所有应用程序设置的JSON对象。

<强> appSettings.php

<?php

$appSettings = [];

foreach ($_SERVER as $key => $value) {

    if(preg_match('/^APPSETTING_/', $key)) {
        $appSettings[str_replace('APPSETTING_', '', $key)] = $value;
    }
}

header('Content-Type: application/json');
echo json_encode($appSettings);

答案 1 :(得分:0)

也许有人仍然需要它。我建议与选择的技术保持更近距离,并公开类似于先前php答案的node.js api。

我创建在Azure AppService中公开的终结点com.ibm.ws.install.configmanager.actionengine.ant.utils.ANTLogToCmtLogAdapter</logger> <level>WARNING</level> <class>com.ibm.ws.install.configmanager.logging.LogUtils</class> <method>logException</method> <thread>37</thread> <message>**The exception message is: Execute failed: java.io.IOException: Cannot run program** "C:\IBM\WebSphere\AppServer\bin\launchWsadminListener.bat" (in directory "E:\IBM\WebSphere\AppServer\profileTemplates\default\actions"): **CreateProcess error=2, The system cannot find the file specified**</message> </record> <record> ,如下所示:

在Angular代码的src目录中添加index.js文件:

http://<websitename>.azurewebsites.net/app-settings

因此,响应包含var http = require('http'); var server = http.createServer(function (request, response) { response.writeHead(200, { "Content-Type": "application/json" }); var result = {}; result.someAppSetting = process.env.SomeApplicationSetting; var jsonResult = JSON.stringify(result); response.end(jsonResult); }); var port = process.env.PORT || 1337; server.listen(port); console.log("Server exposing api for reading application settings running at http://localhost:%d", port); 从环境变量检索到的SomeApplicationSetting应用设置的json。当然,您可以采用其他公开变量的策略,例如仅将一些前缀设置添加到json或其他任何变量中。

将index.js添加到angular.json中的资产:

process.env.SomeApplicationSetting

然后在web.config中添加以下重写规则:

"assets": [
  "src/favicon.ico",
  "src/assets",
  "src/web.config",
  "src/index.js"
],

答案 2 :(得分:0)

我查看了所有解决方案,并创建了一个在Azure和本地计算机(本地主机)上都可以使用的解决方案。取决于构建-prod(从天蓝色读取)或dev(从本地资产文件夹读取)蓝色插槽。

也许对某人有帮助。

首先,您需要添加此小型php文件,例如提到的Aaron Chen。 在src文件夹下的Angular结构中:

src / appSettings.php

$appSettings = [];

foreach ($_SERVER as $key => $value) {

    if(preg_match('/^APPSETTING_/', $key)) {
        $appSettings[str_replace('APPSETTING_', '', $key)] = $value;
    }
}

header('Content-Type: application/json');
echo json_encode($appSettings, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);

需要修改angular.json文件。您需要将assets

添加到"src/appSettings.php"
        "assets": [
          "src/favicon.ico",
          "src/assets",
          "src/appSettings.php"
        ],

此解决方案从http://<websitename>.azurewebsites.net/appSettings.php链接中的azure获取所有配置。 这仅在Azure中有效(需要身份验证)。对于本地开发,您需要创建一个Json文件,该文件包含src/assets文件夹下的所有Azure插槽。

`assets/config/backend.json`;

要加载Json需要创建的配置

src / app / app.config.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpBackend  } from '@angular/common/http';
import { AppSettings } from './models/AppSettings.model';
import { environment } from 'src/environments/environment';

@Injectable()
export class AppConfig {
    static appSettings: AppSettings;

    private http: HttpClient;
    constructor( handler: HttpBackend) {
        this.http = new HttpClient(handler);
    }

    public load() {
        let backendConfigUrl: string;
        if (environment.production) {
            backendConfigUrl = window.location.origin + '/appsettings.php';
        } else {
            backendConfigUrl = `assets/config/backend.json`;
        }
        console.log(backendConfigUrl);

        return new Promise<void>((resolve, reject) => {
            this.http.get<AppSettings>(backendConfigUrl).toPromise().then((response: AppSettings) => {
                AppConfig.appSettings = response;
                resolve();
            }).catch((response: any) => {
               reject(`Could not load file ${backendConfigUrl}: ${JSON.stringify(response)}`);
            });
        });
    }
}

然后修改src/app/app.module.ts以在应用程序启动之前加载配置。

export function initializeApp(appConfig: AppConfig) {
  return () => appConfig.load().then(() => {
    console.log(AppConfig.appSettings)
  });
}

 providers: [
    AppConfig,
    {
      provide: APP_INITIALIZER,
      useFactory: initializeApp,
      deps: [AppConfig],
      multi: true
    },
  ]

ng build从本地assets文件夹中加载配置。 To ng build --prod从Azure读取配置。与ng serveng serve --prod

相同