logo
Laucher

Laucher

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} 就会被替换,最终实现了运行时动态获取容器环境变量。

评论