You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Docker Compose在运行时为React的config.ts动态传环境变量?

解决方案:React应用运行时动态配置API URL(单镜像多环境)

你遇到的核心问题是:REACT_APP_* 这类环境变量是构建阶段被Webpack注入的,一旦打包成Docker镜像,这些值就固定了,没法在运行时修改。要实现单镜像适配多环境,必须把配置逻辑从构建时移到运行时,以下是具体步骤:

1. 重构配置文件,改为运行时读取

修改你的config.ts,让它从全局window对象读取配置(而非构建时的环境变量):

export interface AppConfig {
  apiUrl: string;
}

// 从全局变量读取,同时设置默认值兜底
export const config: AppConfig = {
  apiUrl: (window as any).__APP_CONFIG__?.apiUrl || 'http://default-api.example.com'
};

2. 编写容器启动脚本,动态生成配置

创建一个entrypoint.sh脚本,用来在容器启动时根据环境变量生成全局配置脚本:

#!/bin/sh

# 生成全局配置脚本,注入到静态文件目录
cat > /usr/share/nginx/html/config.js <<EOF
window.__APP_CONFIG__ = {
  apiUrl: "${API_URL:-http://default-api.example.com}"
};
EOF

# 启动Nginx服务(假设用Nginx托管静态文件)
nginx -g 'daemon off;'

给脚本添加执行权限:

chmod +x entrypoint.sh

3. 调整Dockerfile,打包单镜像

用多阶段构建打包React应用,同时把启动脚本加入镜像:

# 构建阶段:编译React应用
FROM node:18-alpine as builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
# 这里用默认值构建,运行时会被覆盖
RUN npm run build

# 运行阶段:用Nginx托管静态文件
FROM nginx:alpine
# 复制编译后的静态文件
COPY --from=builder /app/build /usr/share/nginx/html
# 复制启动脚本
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
# 设置容器启动入口
ENTRYPOINT ["/entrypoint.sh"]

4. 用Docker Compose分环境传参

创建不同环境的Compose配置文件,传入对应环境的API URL:

开发环境(docker-compose.dev.yml)

version: '3.8'
services:
  react-app:
    build: .
    ports:
      - "3000:80"
    environment:
      - API_URL=http://dev-api.example.com

UAT环境(docker-compose.uat.yml)

version: '3.8'
services:
  react-app:
    build: .
    ports:
      - "3001:80"
    environment:
      - API_URL=http://uat-api.example.com

生产环境(docker-compose.prod.yml)

version: '3.8'
services:
  react-app:
    build: .
    ports:
      - "80:80"
    environment:
      - API_URL=http://prod-api.example.com

启动对应环境的容器:

# 开发环境
docker-compose -f docker-compose.dev.yml up -d

# UAT环境
docker-compose -f docker-compose.uat.yml up -d

# 生产环境
docker-compose -f docker-compose.prod.yml up -d

5. 在React应用中使用动态配置

在需要调用API的地方,直接导入config.ts的配置即可:

import { config } from './config';

// 示例:调用API
fetch(`${config.apiUrl}/users`)
  .then(res => res.json())
  .then(data => console.log(data));

关键补充:在index.html中引入配置脚本

修改public/index.html,把生成的config.js放在React bundle之前加载,确保全局变量在应用启动前就存在:

<!DOCTYPE html>
<html lang="en">
  <head>
    <!-- 其他头部内容 -->
    <!-- 先加载全局配置脚本 -->
    <script src="%PUBLIC_URL%/config.js"></script>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

这个方案的核心是:容器启动时动态生成全局配置脚本,React应用运行时读取这个脚本的变量,实现了单镜像适配多环境,不需要为每个环境重新构建镜像。

内容的提问来源于stack exchange,提问作者user26582282

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 08:49:51