React Vite应用Docker容器:本地构建正常,Hub拉取后环境变量未识别
React环境变量在Docker Hub拉取的镜像中无法识别问题
问题场景
本地运行npm start时,环境变量可正常识别;本地构建Docker镜像并运行,变量也能正常加载。但将代码推送到master分支并同步镜像至Docker Hub后,拉取镜像运行时,即使通过docker inspect确认环境变量已传入容器,React仍无法识别这些变量。
.env文件内容
REACT_APP_URL=http://localhost:8080 REACT_APP_API_URL=http://localhost:4500/api REACT_APP_VEHICLE_IMAGE_URL='URL' REACT_APP_NAME=NAME REACT_APP_GA_TRACKING_ID=
本地正常运行命令
# 本地构建镜像 docker build . -t container # 运行容器 docker run -p 8080:8080 --env-file .env -d --name container --restart always container
Dockerfile内容
FROM node:16-alpine WORKDIR /app COPY package.json . RUN npm install COPY . . RUN npm run build EXPOSE 8080 CMD [ "npm", "run", "preview" ]
异常场景命令
# 拉取Docker Hub镜像 docker pull user/repository_test # 运行容器 docker run -p 8080:8080 --env-file .env -d --name repo --restart always user/repository_test
容器环境变量已存在但未被React识别的截图:
问题原因
React的环境变量是在构建阶段注入到静态文件中的,而非运行时生效。本地构建镜像时,你的.env文件内容会被打包进build目录;但推送到Docker Hub的镜像,是在CI/CD环境(或你推送前的构建环境)中构建的,该环境没有你的本地.env变量,导致构建后的静态文件中没有注入这些变量。即使运行容器时传入环境变量,也无法覆盖已打包的静态内容。
解决方案
方案1:构建镜像时传入环境变量
确保构建Docker镜像时注入环境变量,让React在构建阶段获取正确值:
- 修改Dockerfile,添加构建参数声明并设置为环境变量:
FROM node:16-alpine WORKDIR /app # 声明需要的构建参数 ARG REACT_APP_URL ARG REACT_APP_API_URL ARG REACT_APP_VEHICLE_IMAGE_URL ARG REACT_APP_NAME ARG REACT_APP_GA_TRACKING_ID # 将构建参数转为容器环境变量,供React构建时读取 ENV REACT_APP_URL=$REACT_APP_URL ENV REACT_APP_API_URL=$REACT_APP_API_URL ENV REACT_APP_VEHICLE_IMAGE_URL=$REACT_APP_VEHICLE_IMAGE_URL ENV REACT_APP_NAME=$REACT_APP_NAME ENV REACT_APP_GA_TRACKING_ID=$REACT_APP_GA_TRACKING_ID COPY package.json . RUN npm install COPY . . RUN npm run build EXPOSE 8080 CMD [ "npm", "run", "preview" ]
- 构建镜像时传入参数(本地或CI/CD环境执行):
docker build . -t user/repository_test \ --build-arg REACT_APP_URL=http://localhost:8080 \ --build-arg REACT_APP_API_URL=http://localhost:4500/api \ --build-arg REACT_APP_VEHICLE_IMAGE_URL='URL' \ --build-arg REACT_APP_NAME=NAME \ --build-arg REACT_APP_GA_TRACKING_ID=
- 推送该镜像到Docker Hub,拉取后运行即可正常识别变量。
方案2:运行时动态注入环境变量
适合需要在运行容器时动态变更变量的场景:
- 在
public/index.html中添加全局变量占位:
<script> window.env = { REACT_APP_URL: "%REACT_APP_URL%", REACT_APP_API_URL: "%REACT_APP_API_URL%", REACT_APP_VEHICLE_IMAGE_URL: "%REACT_APP_VEHICLE_IMAGE_URL%", REACT_APP_NAME: "%REACT_APP_NAME%", REACT_APP_GA_TRACKING_ID: "%REACT_APP_GA_TRACKING_ID%" }; </script>
- 修改应用中读取环境变量的代码,改为读取
window.env:
// 原代码:process.env.REACT_APP_API_URL // 修改后:window.env.REACT_APP_API_URL const apiUrl = window.env.REACT_APP_API_URL;
- 修改Dockerfile的启动命令,在运行时替换占位符:
FROM node:16-alpine WORKDIR /app COPY package.json . RUN npm install COPY . . RUN npm run build EXPOSE 8080 # 启动时替换index.html中的占位符为容器环境变量 CMD ["/bin/sh", "-c", "envsubst < /app/build/index.html > /app/build/index.html.tmp && mv /app/build/index.html.tmp /app/build/index.html && npm run preview"]
- 构建并推送镜像到Docker Hub,运行时通过
--env-file传入变量即可生效。
内容的提问来源于stack exchange,提问作者n9p4
相关产品推荐
相关产品推荐

