docker 在运行时阅读Angular中的服务器环境变量

jjhzyzn0  于 2023-03-07  发布在  Docker
关注(0)|答案(3)|浏览(139)

我是angular的新手。我已经在aws的docker容器中部署了一个angular应用程序。这个应用程序需要连接到aws s3 bucket。我不需要硬编码aws键,所以我在docker中设置了一个环境变量。angular的部署使得ng build的dist文件夹由nginx docker容器服务。
一旦dist文件夹中的内容被提供给服务器,是否可以通过angular读取服务器环境变量?就像php和nodejs中的env函数一样

2sbarzqh

2sbarzqh1#

不幸的是,无法在Angular中读取类似于nodejs或 Boot 等服务器框架提供的机制的环境变量。
不过,您可以在Angular应用程序引导之前从服务器加载环境(请在选择此路径之前阅读下面的缺点)。

从服务器加载环境变量:

  • 从根模块(例如AppModule)中删除引导组件,使其不会自动引导
  • 在root中创建一个加载环境变量的单例服务,例如:
import { Injectable } from "@angular/core";

@Injectable({ providedIn: "root" })
export class EnvService {
  public myEnv: string;

  fetchEnv() {
    // This has to retrieved from some server.
    return fetch("some-url").then(env => {this.myEnv = env.myEnv; return Promise.resolve("env loaded");};
  }
}
  • 延迟根模块中的引导,直到加载环境:
@NgModule({
  imports: [BrowserModule, FormsModule],
  declarations: [AppComponent, HelloComponent]
})
export class AppModule {
  constructor(private envService: EnvService) {}
  ngDoBootstrap(app) {
    this.envService.fetchEnv().then(() => app.bootstrap(AppComponent));
  }
}

这种方法有两个缺点:

  • 在加载其他env变量之前,必须知道从中检索env设置的url
  • 如果无法加载环境变量,Angular应用将无法 Boot 。当您使用Docker时,您可以在Docker容器内托管一个小型Web服务器,该服务器为Angular应用提供专用端点上的环境变量。然而,这可能会带来自身的问题,因为这会使创建Angular Docker容器变得更加复杂。

因此,我建议在构建期间配置env变量。
有两种方法可以在构建期间设置环境变量

1)使用自定义Webpack配置在构建中设置环境变量

看这个article
您可以在angular.json中指定自定义webpack配置:

"architect": {
        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "customWebpackConfig": {
              "path": "extra-webpack.config.js"
            },
...

webpack配置文件如下所示:

const webpack = require('webpack');

module.exports = {
  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        // Here you can set your env variables.
        SERVER_URL: JSON.stringify(process.env.SERVER_URL)
      }
    })
  ]
}

此方法需要更多的依赖项:

@angular-builders/custom-webpack
dotenv

2)在构建期间动态创建环境文件

例如,请参见自动生成的src/environments/environment. prod. ts。您可以使用正确的环境值生成此文件,或者在构建期间替换此文件中的占位符。

编辑:也可以参考The Fabio的答案。你可能不希望你的用户知道S3 bucket,如果可能的话,应该通过一个Web服务器将你的请求路由到bucket。

oknwwptz

oknwwptz2#

php和nodejs运行在服务器端,这就是为什么它们可以访问服务器环境变量。
当Angular在浏览器中运行时,你的angular应用程序可以读取的任何内容都会暴露给客户端。我想你不希望你的AWS密钥在客户端上到处浮动,任何用户都可以准备好它们。这会使你的后端暴露给恶意使用。
如果您真的选择了这条路径,您可以在angular应用正在对话的服务器应用中创建一个端点来公开服务器环境变量。
更常见的模式是让服务器端点向Angular 变量而不是环境变量提供数据:
1.你的Angular 发球叫发球端点;
1.服务器利用其配置和变量获取数据;
1.所述服务器以所述数据响应所述Angular 服务调用;
我过于简化了服务器交互,因为我建议您将其与此问题分开阅读。This post应该有助于您开始后端/前端分离。

hec6srdp

hec6srdp3#

我知道这是一个老问题,但我想添加一个潜在的选择,任何人搜索这个。
如果您使用NGinx或类似的工具在Docker容器中部署Angular应用程序,我使用了一个名为confd的工具,该工具由@kelseyhightower提供,位于https://github.com/kelseyhightower/confd
基本上就是修改index.html,使其包含confd模板变量,创建一个“config”对象,然后在Angular代码中访问该对象。然后可以使用该“config”对象中的值来设置environment.ts值。需要将Confd设置为在容器启动时运行。
这将添加到Dockerfile x1c 0d1x的末尾
这将被添加到index.html文件中。

这是容器的启动脚本。作为Dockerfile步骤的一部分,我将其复制到/usr/local/bin中。

访问environment.ts文件

中的值
到目前为止,对我来说效果很好,但您可能需要为不基于容器的部署找到替代解决方案。

相关问题