如何将环境变量传递到前端Web应用程序? [英] How to pass environment variables to a frontend web application?
问题描述
我正在尝试将前端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因子的应用程序原理,可以在 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?
推荐答案
我解决此问题的方法如下:
The way that I resolved this is as follows:
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,每次完成容器的docker运行时,都会执行一次entryPoint.
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.在CMD之前在dockerfile中添加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.将图像与环境放在一起或使用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屋!