
Laucher
2025年 03月 29日
0
Vue 2 + Docker + config.js + envsubst 实现运行时动态获取容器环境变量
通过 Vue 2 + Docker + config.js 和 envsubst 实现运行时动态获取容器环境变量,无需重新构建镜像。

背景
在 Vue 2 项目中,通常使用 “process.env” 来管理环境变量。但在 Docker 容器化部署时:
- 环境变量在构建时就被固定,无法在运行时动态修改。
- 多环境(测试 / 生产) & 多区域(项目)部署时,无法灵活切换变量。
为了解决这个问题,计划使用 “config.js” + “envsubst”,让环境变量在运行时动态替换,而无需重新构建镜像。
1. 方案核心
- 环境变量:VUE_APP_PAY_BRAND。
- 构建阶段:Vue 代码不会在ENV写死环境变量,而是通过 “config.js” 读取环境变量。
- 运行阶段:
- 通过 “envsubst” 替换 “config.js” 里的 ”${VUE_APP_PAY_BRAND}“,根据 “docker run “传入的环境变量动态设置值。
- 不同环境 & 不同区域 使用 相同的 Docker 镜像,但运行时加载不同的 “VUE_APP_PAY_BRAND” 值。
2. 创建 public/config.js
在 “public/config.js” 里写入:
window.APP_CONFIG = {
VUE_APP_PAY_BRAND: "${VUE_APP_PAY_BRAND}" // 运行时 `envsubst` 会替换这里的值
};
这里的 ”${VUE_APP_PAY_BRAND}” 只是一个占位符,不会在构建时被 Webpack 解析,而是在容器运行时被替换。
并在html文件导入”config.js”
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title><%= webpackConfig.name %></title>
<!-- 在 Vue 代码运行前加载 config.js -->
<script src="/config.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
3. 修改 Vue 代码,读取 config.js
在 main.js 或 axios 配置中,读取 window.APP_CONFIG:
const PAY_BRAND = window.APP_CONFIG?.VUE_APP_PAY_BRAND || "Tic";
export default PAY_BRAND;
这样:
构建时 不会写死 “VUE_APP_PAY_BRAND”。
运行时 由 config.js 提供 “VUE_APP_PAY_BRAND”,无需重新构建镜像。
4. 修改 Dockerfile
注意:不同项目的Dockerfile有所不同,需根据项目而定
# 基础镜像
FROM nginx:1.26.2
# 复制静态文件
COPY dist /data/statics/payment-admin
# 复制前端 `config.js` 文件(使用占位符)
COPY public/config.js /usr/share/nginx/html/config.js
# 复制配置文件
COPY nginx.conf /etc/nginx/nginx.conf
# 删除默认配置
RUN rm -f /etc/nginx/conf.d/default.conf
# 复制配置文件
COPY manage.conf /etc/nginx/conf.d/manage.conf
# 替换 config.js 中的占位符
RUN chmod 777 /usr/share/nginx/html/config.js
# 暴露端口
EXPOSE 80
# 启动命令,运行时替换占位符
CMD ["/bin/sh", "-c", "envsubst < /usr/share/nginx/html/config.js > /data/statics/payment-admin/config.js && exec nginx -g 'daemon off;'"]
5.使用Docker在应用平台(Jenkins) 构建镜像
在 Jenkinsfile 里,可以这样构建:
docker build -t my-vue-app .
6. 运行时动态注入 “VUE_APP_PAY_BRAND”
测试环境
docker run -e VUE_APP_PAY_BRAND=Tic -p 8080:80 my-vue-app
生产环境(不同地区)
# -Tic
docker run -e VUE_APP_PAY_BRAND=Tic -p 8080:80 my-vue-app
# -Yere
docker run -e VUE_APP_PAY_BRAND=Yere -p 8081:80 my-vue-app
# -Otg
docker run -e VUE_APP_PAY_BRAND=Otg -p 8082:80 my-vue-app
这样:
- 不同区域 用的是同一个 Docker 镜像,但 “VUE_APP_PAY_BRAND” 不同。
- 不需要为每个区域重新构建镜像,只需修改 docker run 时的环境变量。
7. Kubernetes 部署
如果使用 Kubernetes,可以在 Deployment.yaml 里注入环境变量:
containers:
- name: my-vue-app
image: my-vue-app:latest
env:
- name: VUE_APP_PAY_BRAND
value: "Yere"
最后,在容器里查找ENV,能找到您配置的环境变量 “VUE_APP_PAY_BRAND” 的话。
# env
HOSTNAME=9978357d47a9
HOME=/root
PKG_RELEASE=1~bookworm
DYNPKG_RELEASE=2~bookworm
TERM=xterm
NGINX_VERSION=1.26.2
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
NJS_VERSION=0.8.5
NJS_RELEASE=1~bookworm
VUE_APP_PAY_BRAND=Tic
PWD=/
#
容器启动时 config.js 里的 ${VUE_APP_PAY_BRAND} 就会被替换,最终实现了运行时动态获取容器环境变量。