Angularjs Angular2应用程序的配置-nginx和docker

Angularjs Angular2应用程序的配置-nginx和docker,angularjs,angular,nginx,docker,Angularjs,Angular,Nginx,Docker,我有一个REST后端服务,位于某个服务器上,前端应用程序由angular开发。 我正在使用Angular CLI构建应用程序。我的后端服务器的位置位于环境文件中。 我的应用程序的要求是,我提供两个docker图像。一个是我的后端服务器(JavaSpringBootApp),第二个是使用ngbuildmyApp命令的静态html构建。然后,我将内容oddist目录复制到docker图像上的适当目录,如下所示 问题是,后端和前端可能在不同的服务器上工作。是否有任何方法可以配置前端应用程序,以便根据容

我有一个REST后端服务,位于某个服务器上,前端应用程序由angular开发。 我正在使用Angular CLI构建应用程序。我的后端服务器的位置位于环境文件中。 我的应用程序的要求是,我提供两个docker图像。一个是我的后端服务器(JavaSpringBootApp),第二个是使用
ngbuildmyApp
命令的静态html构建。然后,我将内容od
dist
目录复制到docker图像上的适当目录,如下所示


问题是,后端和前端可能在不同的服务器上工作。是否有任何方法可以配置前端应用程序,以便根据容器的开始更改后端服务器的位置?

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

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

解决方案1(“客户端”):env.js资产+sed 想法是让Angular客户端从HTTP服务器加载一个
env.js
文件。此
env.js
将包含API URL,并且在启动时可由容器修改。这是您在问题评论中讨论的内容

在angular app assets文件夹中添加一个
env.js
src/assets
for me with angular cli):

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

<head>
  <meta charset="utf-8">
  <base href="/">
  <script src="env.js"></script>
</head>
在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文档)

解决方案2(纯服务器端):nginx proxy config+envsubs 我对以前的解决方案不满意,因为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;
    }
}
run.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;'
#/垃圾箱/垃圾箱
#替代环境变量
envsubs“$MY\u API\u URL”\
/etc/nginx/conf.d/default.conf
#启动服务器
nginx-g“守护进程关闭;”
envsubt
允许您使用类似shell的语法替换字符串中的环境变量

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


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

不太可能-当容器启动时,后端位置已经烘焙到由
ng build
生成的静态HTML和JS中。我们通过从
https://some.url
和后端可在
https://some.url/api
,因此我们可以使用相对路由,但这可能不是Docker容器的选项。如何使用前端服务的配置文件,并在Docker容器的开头交换它?该配置文件会做什么?同样,您有静态HTML和JS;如果您通过CLI进行构建,那么使用例如
environment.whatever.ts
来注入信息就太晚了。前端的Docker实际上只是提供预编译文件。我可以使用“资产”文件夹存储一些config.json文件,然后在加载html时从angular加载它吗?那么唯一的问题就是在docker启动时使用'sed'od交换它。你说的“从角度加载”是什么意思?你是说从客户方面?因为请记住,JS实际上是在那里运行的,不是在容器中,也不是在加载HTML之后。
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;
    }
}
#!/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;'