如何将环境变量传递给前端 Web 应用程序? [英] How to pass environment variables to a frontend web application?

查看:42
本文介绍了如何将环境变量传递给前端 Web 应用程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试容器化前端 Web 应用程序,但在弄清楚如何传递环境变量时遇到了麻烦.该应用程序是一个 Angular 应用程序,因此它是 100% 的客户端.

I am trying to containerize a frontend web application and I am having troubles to figure out how to pass environment variables. The application is a Angular application, so it is 100% client-side.

在典型的后端服务中,传递环境变量很容易,因为一切都在同一主机上运行,​​因此后端服务可以轻松选择环境变量.但是,在前端应用程序中,这是不同的:应用程序运行在客户端的浏览器中.

In a typical backend service, passing environment variables is easy, as everything is running on the same host, so the environment variables can be easily picked by the backend service. However, in a frontend application, this is different: the application is running in the browser of the client.

我想通过环境变量配置我的应用程序,因为这使得部署更容易.所有配置都可以在 docker-compose.yml 中完成,无需维护多个镜像,每个可能的环境一个.只有一个不可变的图像.这遵循 12-factor 应用程序哲学,可以在 https://12factor.net/config 上找到.

I want to configure my application via environment variables, as this makes deployment much easier. All configuration can be done in docker-compose.yml and there is no need to maintain several images, one for every possible environment. There is just one single immutable image. This follows the 12-factor application philosophy, as can be found on https://12factor.net/config.

我正在构建我的应用程序映像,如下所示:

I am building my application image as following:

FROM node:alpine as builder
COPY package.json ./
RUN npm i && mkdir /app && cp -R ./node_modules ./app
WORKDIR /app
COPY . .
RUN $(npm bin)/ng build

FROM nginx:alpine
COPY nginx/default.conf /etc/nginx/conf.d/
RUN rm -rf /usr/share/nginx/html/*
COPY --from=builder /app/dist /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]

app/config.ts 中,我有:

export const config = {
    REST_API_URL: 'http://default-url-to-my-backend-rest-api'
};

理想情况下,我想在我的 docker-compose.yml 中做这样的事情:

Ideally, I want to do something like this in my docker-compose.yml:

backend:
  image: ...
frontend:
  image: my-frontend-app
  environment:
    - REST_API_URL=http://backend:8080/api

所以我相信我应该修改这个 app/config.ts 以用环境变量替换 REST_API_URL.因为我更喜欢不可变的 Docker 镜像(所以我不想在构建过程中进行这个替换),我很困惑如何在这里取得进展.我相信我应该支持在 nginx 代理启动之前在运行时更改 app/config.ts.然而,这个文件被缩小和 webpack 捆绑的事实使得这更加困难.

So I believe I should alter this app/config.ts to replace REST_API_URL with the environment variable. As I prefer an immutable Docker image (so I do not want to do this replace during the build), I am quite puzzled how to progress here. I believe I should support to alter the app/config.ts at runtime before the nginx proxy is started. However, the fact that this file is minified and webpack-bundled, makes this more diffucult.

有什么想法可以解决这个问题吗?

Any ideas how to tackle this?

推荐答案

我的解决方法如下:

1.在enviroment.prod.ts中设置一个唯一且可识别的字符串值:

1.Set the value in the enviroment.prod.ts with a unique and identificable String:

export const environment = {
  production: true,
  REST_API_URL: 'REST_API_URL_REPLACE',
};

2.创建一个entryPoint.sh,这个entryPoint会在你每次对容器进行docker run时执行.

2.Create a entryPoint.sh, this entryPoint will be executed every time that you done a docker run of the container.

#!/bin/bash
set -xe
: "${REST_API_URL_REPLACE?Need an api url}"

sed -i "s/REST_API_URL_REPLACE/$REST_API_URL_REPLACE/g" /usr/share/nginx/html/main*bundle.js

exec "$@"

如您所见,此入口点获取REST_API_URL_REPLACE"参数并将其替换(在本例中) main*bundle.js 文件中的 var 值.

As you can see, this entrypoint get the 'REST_API_URL_REPLACE' argument and replace it (in this case) in the main*bundle.js file for the value of the var.

3.在dockerfile中CMD前添加entrypoint.sh(需要执行权限):

3.Add the entrypoint.sh in the dockerfile before the CMD (it need execution permissions):

FROM node:alpine as builder
COPY package.json ./
RUN npm i && mkdir /app && cp -R ./node_modules ./app
WORKDIR /app
COPY . .
RUN $(npm bin)/ng build --prod

FROM nginx:alpine
COPY nginx/default.conf /etc/nginx/conf.d/
RUN rm -rf /usr/share/nginx/html/*
COPY --from=builder /app/dist /usr/share/nginx/html

# Copy the EntryPoint
COPY ./entryPoint.sh /
RUN chmod +x entryPoint.sh

ENTRYPOINT ["/entryPoint.sh"]
CMD ["nginx", "-g", "daemon off;"]

4.使用 env 或使用 docker-compose 启动镜像(斜线必须转义):

4.Lauch the image with the env or use docker-compose (the slash must be escaped):

docker run -e REST_API_URL_REPLACE='http://backend:8080/api'-p 80:80 image:tag

可能存在一个更好的解决方案,不需要在缩小的文件中使用正则表达式,但这工作正常.

Probably exists a better solution that not need to use a regular expresion in the minified file, but this works fine.

这篇关于如何将环境变量传递给前端 Web 应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆