【问题标题】:Configuration of Angular2 application - nginx and dockerAngular2应用的配置——nginx和docker
【发布时间】:2017-01-13 22:25:23
【问题描述】:

我有一个位于某些服务器上的 REST 后端服务和 Angular 的前端应用程序。 我正在使用 Angular CLI 构建应用程序。我的后端服务器的位置位于环境文件中。 我的应用程序的要求是我提供两个 docker 图像。一个是我的后端服务器(Java Spring Boot 应用程序),第二个是使用 ng build myApp 命令的静态 html 构建。然后我将 od dist 目录复制到 docker 映像上的正确目录,如下所示Nginx docker image

问题是,后端和前端可能在不同的服务器上工作。有什么方法可以配置我的前端应用程序,我可以根据容器的启动更改后端服务器位置?

【问题讨论】:

  • 并非如此——当容器启动时,后端位置已经被烘焙到ng build 生成的静态 HTML 和 JS 中。我们在 Cloud Foundry 上通过使用https://some.url 提供的 Web 应用程序和https://some.url/api 提供的后端解决了这个问题,因此我们可以使用相对路由,但这可能不是 Docker 容器的选项。
  • 前端服务的配置文件如何在docker容器启动时进行交换?
  • 那个配置文件会做什么?再次,您有 静态 HTML 和 JS;如果您通过 CLI 构建,那么使用例如为时已晚。 environment.whatever.ts 注入信息。前端的 Docker 实际上只是提供预编译文件。
  • 我可以使用 'assets' 文件夹来存储一些 config.json 文件,然后在加载 html 时从 angular 加载它吗?那么唯一的问题就是在 docker 启动时使用 'sed' od swap 它。
  • 你是什么意思“从角度加载”?你的意思是从客户端?因为请记住,这是 JS 实际运行的地方,不在在你的容器中,直到 HTML 被加载之后。

标签: angularjs angular nginx docker


【解决方案1】:

我知道这是一个老问题,但我遇到了完全相同的问题,我花了一段时间才解决。希望这对来自搜索引擎的人有所帮助。

我找到了 2 个解决方案(我最终选择了第二个)。两者都允许您在 docker 中使用环境变量来配置您的 API URL。

解决方案 1(“客户端”端):env.js 资产 + sed

这个想法是让你的 Angular 客户端从你的 HTTP 服务器加载一个env.js 文件。这个env.js 将包含 API URL,并且可以在容器启动时进行修改。这就是你在问题 cmets 中讨论的内容。

在您的 Angular 应用资产文件夹中添加一个 env.jssrc/assets 对我来说使用 angular-cli):

var MY_APP_ENV = {
  apiUrl: 'http://localhost:9400',
}

在您的index.html 中,您将加载您的环境:

<head>
  <meta charset="utf-8">
  <base href="/">
  <script src="env.js"></script>
</head>

在你的 environment.ts 中,你可以使用变量:

declare var MY_APP_ENV: any;

export const environment = {
  production: false,
  apiUrl: MY_APP_ENV.apiUrl
};

在你的 NGINX Dockerfile 中做:

FROM nginx:1.11-alpine

COPY tmp/dist /usr/share/nginx/html
COPY run.sh /run.sh

CMD ["sh", "/run.sh"]

run.sh 脚本是 sed 魔法发生的地方:

#!/bin/sh

# API
/bin/sed -i "s|http://localhost:9400|${MY_API_URL}|" /usr/share/nginx/html/env.js

nginx -g 'daemon off;'

在您的 Angular 服务中,使用 environment.apiUrl 连接到 API(您需要导入环境,请参阅 Angular 2 文档)。

方案二(纯服务端):nginx proxy config + envsubst

我对以前的解决方案不满意,因为 API URL 需要从主机的角度来看,它不能在我的 docker-compose 设置中使用另一个容器主机名。

所以我想:很多人使用 NGINX 作为代理服务器,为什么不通过这种方式将/api 代理到我的其他容器。

Dockerfile:

FROM nginx:1.11-alpine

COPY tmp/dist /usr/share/nginx/html
COPY frontend.conf.template /etc/nginx/conf.d/frontend.conf.template
COPY run.sh /run.sh

CMD ["/bin/sh", "/run.sh"]

frontend.conf.template:

server {
    listen       80;
    server_name  myserver;

    # API Server
    location /api/ {
        proxy_pass ${MY_API_URL}/;
    }

    # Main
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        try_files $uri$args $uri$args/ /index.html;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

运行.sh:

#!/bin/sh

# Substitute env vars
envsubst '$MY_API_URL' \
< /etc/nginx/conf.d/frontend.conf.template \
> /etc/nginx/conf.d/default.conf

# Start server
nginx -g 'daemon off;'

envsubt 允许您使用类似 shell 的语法替换字符串中的环境变量。

然后使用/api/xyz 从 Angular 应用程序连接到 API。

我认为第二种解决方案更清洁。 API URL 可以是 docker-compose 设置中的 API docker 容器名称,这很好。客户不参与,它是透明的。但是,它依赖于 NGINX。

【讨论】:

    猜你喜欢
    • 2016-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    • 1970-01-01
    • 2015-12-31
    • 2021-08-20
    • 2020-04-30
    相关资源
    最近更新 更多