在Webpack React项目中获取Docker运行时环境变量的问题
解决Docker运行时环境变量在自定义Webpack React应用中的访问问题
问题本质
你的问题确实和Webpack的默认行为直接相关:Webpack会在构建阶段将代码中的process.env变量替换为构建时的具体值,而非在容器运行时读取环境变量。CRA之所以能支持你说的方式,是因为它内置了针对环境变量的特殊处理逻辑(开发环境通过devServer动态注入,部分生产部署场景下也支持运行时替换),但自定义Webpack配置默认没有这个能力。
实现运行时读取环境变量的方案
要避免将环境变量硬编码到构建产物中,同时能读取Docker运行时传入的变量,你需要通过容器启动时替换HTML占位符的方式实现:
1. 修改HTML模板,添加全局环境变量占位符
在src/index.html中插入一个脚本块,定义全局环境变量的占位符:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>React App</title> </head> <body> <div id="root"></div> <!-- 运行时环境变量占位符 --> <script> window.appEnv = { REACT_APP_NAME: '{{REACT_APP_NAME}}' }; </script> </body> </html>
2. 编写容器启动脚本
在项目根目录创建start.sh脚本,负责启动前替换HTML中的占位符为实际环境变量:
#!/bin/sh # 替换占位符为容器运行时的环境变量,未传入时使用默认值 sed -i "s/{{REACT_APP_NAME}}/${REACT_APP_NAME:-默认API地址}/g" /usr/share/nginx/html/index.html # 启动静态文件服务器(以Nginx为例) nginx -g 'daemon off;'
给脚本添加执行权限:
chmod +x start.sh
3. 更新Dockerfile
确保Dockerfile将构建产物复制到服务器目录,并使用启动脚本启动容器:
# 构建阶段 FROM node:18-alpine as build-stage WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # 生产阶段 FROM nginx:stable-alpine COPY --from=build-stage /app/dist /usr/share/nginx/html COPY start.sh /usr/local/bin/start.sh RUN chmod +x /usr/local/bin/start.sh CMD ["start.sh"]
4. 在React代码中访问变量
现在可以通过全局变量window.appEnv.REACT_APP_NAME获取运行时环境变量:
function App() { return ( <div className="App"> <h1>当前API地址:{window.appEnv.REACT_APP_NAME}</h1> </div> ); } export default App;
关键说明
- 这种方式完全在容器运行时注入环境变量,不会将敏感信息硬编码到构建产物中。
- 如果需要添加更多环境变量,只需在HTML模板和启动脚本中同步增加占位符和替换逻辑即可。
- 若不使用Nginx,可替换启动脚本中的服务器命令(比如用
serve -s dist,需在生产镜像中安装serve)。
内容的提问来源于stack exchange,提问作者Musadiq Khan
相关产品推荐
相关产品推荐

