Vue 2 + Docker + config.js + envsubst 实现运行时动态获取容器环境变量

Vue 2 + Docker + config.js + envsubst 实现运行时动态获取容器环境变量

2025-03-29
envsubstDockervue
AI 智能概括

针对 Vue 2 Docker 部署中环境变量构建固化的痛点,巧妙利用 config.js 与 envsubst 实现运行时动态替换。该方案允许同一镜像在不同环境与区域间灵活切换,无需重新构建,既简化了运维流程,又提升了交付效率

Powered by DeepSeek

背景

在 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" 里写入:

JavaScript
window.APP_CONFIG = {
  VUE_APP_PAY_BRAND: "${VUE_APP_PAY_BRAND}", // 运行时 `envsubst` 会替换这里的值
};

这里的 "VUE_APP_PAY_BRAND" 只是一个占位符,不会在构建时被 Webpack 解析,而是在容器运行时被替换。

并在 html 文件导入"config.js"

HTML
<!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:

JavaScript
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 有所不同,需根据项目而定

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 里,可以这样构建:

shell
  docker build -t my-vue-app .

6. 运行时动态注入 "VUE_APP_PAY_BRAND"

测试环境

shell
  docker run -e VUE_APP_PAY_BRAND=Tic -p 8080:80 my-vue-app

生产环境(不同地区)

shell
  # -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 里注入环境变量:

YAML
containers:
  - name: my-vue-app
    image: my-vue-app:latest
    env:
      - name: VUE_APP_PAY_BRAND
        value: "Yere"

最后,在容器里查找 ENV,能找到您配置的环境变量 "VUE_APP_PAY_BRAND" 的话。

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

发布于 2025-03-29