Vite+React部署时无法读取Terraform配置的环境变量问题
Vite React Docker部署后无法读取环境变量的问题排查与解决
问题原因
Vite对环境变量的处理是构建时注入的:
- 本地开发时,Vite dev server会实时加载
.env文件,把带VITE_前缀的变量注入到前端代码中,所以能正常读取。 - Docker部署时如果先构建镜像再传入环境变量,此时构建过程已经完成,打包后的静态代码里没有预留运行时读取变量的逻辑,自然读不到Terraform从AWS Parameter Store传入的变量。哪怕加/减
VITE_前缀也没用,因为运行时的环境变量无法被静态前端代码直接获取。
解决方法
1. 构建时注入变量(适合变量提前已知的场景)
如果QA环境的变量在构建镜像阶段就能确定,直接在构建时把变量注入到代码里:
- 修改Dockerfile,在构建步骤传入环境变量:
# 构建阶段 FROM node:18-alpine as builder WORKDIR /app COPY package*.json ./ RUN npm install COPY . . # 接收构建参数并设置为环境变量 ARG VITE_TEST_URL ENV VITE_TEST_URL=$VITE_TEST_URL RUN npm run build # 运行阶段 FROM nginx:alpine COPY --from=builder /app/dist /usr/share/nginx/html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]
- 用Terraform构建镜像时,把AWS Parameter Store的变量作为构建参数传入:
resource "docker_image" "react_app" { name = "your-qa-react-image" build { context = "./your-app-directory" args = { VITE_TEST_URL = data.aws_ssm_parameter.test_url.value } } }
前端代码继续用import.meta.env.VITE_TEST_URL读取即可。
2. 运行时动态注入变量(适合多环境复用镜像的场景)
如果需要同一镜像适配不同环境,在容器运行时动态传入变量:
- 在项目的
index.html中添加一个全局变量占位符:
<script> window.appEnv = { testUrl: '%VITE_TEST_URL%' }; </script>
- 修改Dockerfile,添加启动脚本替换占位符:
# 构建阶段(和之前一致) FROM node:18-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 start.sh /start.sh RUN chmod +x /start.sh EXPOSE 80 CMD ["/start.sh"]
- 编写
start.sh脚本:
#!/bin/sh # 替换index.html中的占位符 sed -i "s/%VITE_TEST_URL%/$VITE_TEST_URL/g" /usr/share/nginx/html/index.html # 启动nginx服务 nginx -g "daemon off;"
- Terraform部署容器时,把变量作为环境变量传入:
resource "docker_container" "react_app" { image = docker_image.react_app.name name = "qa-react-app" env = [ "VITE_TEST_URL=${data.aws_ssm_parameter.test_url.value}" ] ports { internal = 80 external = 80 } }
前端代码中通过window.appEnv.testUrl读取变量即可。
3. 确认Vite配置无异常
如果坚持用Vite原生方式,检查vite.config.js是否正确配置了环境变量加载:
import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' export default defineConfig({ plugins: [react()], // 默认加载项目根目录的.env文件,若自定义了envDir需确保路径正确 // envDir: './configs', })
注意:只有带VITE_前缀的变量会被Vite注入到前端代码,且必须在构建阶段传入,运行时传入的变量无法被Vite处理。
内容的提问来源于stack exchange,提问作者JoshWarbi
相关产品推荐
相关产品推荐

