Docker环境变量无法传递至Vue应用 求排查方案
问题分析与解决方案
你的核心问题在于:Vue CLI构建的应用会在构建阶段将VUE_APP_*环境变量静态注入到代码中,而你当前是在容器运行时通过docker-compose的env_file传递变量,这时候代码已经构建完成,无法再读取到运行时的环境变量,所以打印出来是空值。
以下是具体的修复步骤:
1. 修正.env文件格式
先把.env.development里的引号去掉,避免引号被当作变量值的一部分:
VUE_APP_URL=http://localhost:61554
2. 选择适合你的解决方案
方案一:构建镜像时注入环境变量(适合固定环境的镜像)
这种方式会在构建镜像阶段把环境变量写入代码,镜像构建完成后变量值固定。
修改docker-compose.yml
在build部分添加args传递环境变量:
version: '3.4' services: my.ui: image: ${DOCKER_REGISTRY-}myui build: context: . dockerfile: Dockerfile args: - VUE_APP_URL=http://localhost:61554 logging: options: max-file: "10" max-size: "25m" ports: - "8080:8080"
修改Dockerfile
让构建阶段能接收并使用这个变量:
# 构建阶段 FROM node:16-alpine as builder # 接收构建参数 ARG VUE_APP_URL # 设置环境变量,让Vue CLI构建时读取 ENV VUE_APP_URL=$VUE_APP_URL WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build # 生产部署阶段 FROM nginx:alpine COPY --from=builder /app/dist /usr/share/nginx/html EXPOSE 8080 CMD ["nginx", "-g", "daemon off;"]
方案二:运行时动态注入环境变量(适合需要动态切换环境的场景)
如果需要在容器启动时动态修改API地址,不能依赖Vue CLI的静态注入,要通过运行时脚本替换变量。
步骤1:创建环境变量模板
在项目的public目录下新建env.js.template:
window.env = { VUE_APP_URL: '${VUE_APP_URL}' };
步骤2:在index.html中引入模板
在public/index.html的<head>里添加:
<script src="/env.js"></script>
步骤3:修改Dockerfile
添加启动脚本,在容器启动时替换模板变量:
# 构建阶段 FROM node:16-alpine as builder WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build # 生产部署阶段 FROM nginx:alpine COPY --from=builder /app/dist /usr/share/nginx/html # 复制模板和启动脚本 COPY public/env.js.template /usr/share/nginx/html/env.js.template COPY entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh # 设置默认环境变量 ENV VUE_APP_URL=http://localhost:61554 EXPOSE 8080 ENTRYPOINT ["/entrypoint.sh"] CMD ["nginx", "-g", "daemon off;"]
步骤4:创建启动脚本entrypoint.sh
#!/bin/sh # 将环境变量替换到模板中生成env.js envsubst '${VUE_APP_URL}' < /usr/share/nginx/html/env.js.template > /usr/share/nginx/html/env.js # 执行原启动命令 exec "$@"
步骤5:修改Vue代码中的变量读取方式
把原来的process.env.VUE_APP_URL改成读取全局变量:
console.log("API URL: " + window.env.VUE_APP_URL);
最后验证
不管用哪种方案,重新构建镜像并启动容器后,控制台就能正确打印出API地址了。
内容的提问来源于stack exchange,提问作者kickinchicken
相关产品推荐
相关产品推荐

