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

在多环境React Redux生产构建中通过环境变量配置API_ROOT

如何在React-Redux RealWorld应用中用环境变量配置API_ROOT(适配OpenShift/K8s多环境,符合12factor原则)

针对你提到的需求——不用硬编辑src/agent.js,而是通过环境变量在staging、live等生产环境中动态设置API_ROOT,同时遵循12factor的配置与代码分离原则,这里有两种可行方案,推荐第二种更贴合12factor的运行时配置方式:


方案一:构建时注入环境变量(基于Create React App默认机制)

这个项目用的是Create React App(CRA)模板,CRA会自动注入所有以REACT_APP_开头的环境变量到生产构建中,步骤如下:

  1. 修改src/agent.js读取环境变量
    把原来硬编码的API_ROOT替换为从环境变量读取,保留默认值作为 fallback:

    // src/agent.js
    const API_ROOT = process.env.REACT_APP_API_ROOT || 'https://api.realworld.io/api';
    
  2. 在OpenShift中配置构建时环境变量
    为staging和live环境分别创建BuildConfig(或者用同一个BuildConfig加参数切换),注入对应环境的API地址:

    • 先创建一个ConfigMap存储各环境的API地址:
      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: realworld-api-config
      data:
        staging_api_root: "https://staging-api.realworld.io/api"
        live_api_root: "https://api.realworld.io/api"
      
    • 针对staging环境的BuildConfig:
      apiVersion: build.openshift.io/v1
      kind: BuildConfig
      metadata:
        name: realworld-staging-build
      spec:
        source:
          git:
            uri: https://github.com/gothinkster/react-redux-realworld-example-app
            ref: master
        strategy:
          sourceStrategy:
            from:
              kind: ImageStreamTag
              name: nodejs:18
            env:
              - name: REACT_APP_API_ROOT
                valueFrom:
                  configMapKeyRef:
                    name: realworld-api-config
                    key: staging_api_root
        output:
          to:
            kind: ImageStreamTag
            name: realworld-app:staging
      
    • live环境的BuildConfig只需要把key换成live_api_root,输出镜像标签改为live即可。
  3. 部署对应环境的镜像
    构建完成后,用staging/live的镜像分别部署到对应的环境,每个环境的API_ROOT已经打包在镜像里了。


方案二:运行时注入环境变量(更符合12factor原则,推荐)

12factor强调配置应该在运行时与代码分离,同一个镜像可以在任意环境运行。这种方式不需要为不同环境构建镜像,而是在容器启动时动态注入API_ROOT:

  1. 修改public/index.html添加全局环境占位符
    在public/index.html的<head>标签里添加一段脚本,预留占位符供后续替换:

    <!-- public/index.html -->
    <head>
      <!-- 其他内容 -->
      <script>
        window.env = {
          API_ROOT: "%REACT_APP_API_ROOT%"
        };
      </script>
    </head>
    
  2. 修改src/agent.js读取全局环境变量
    把API_ROOT改为读取window上的全局变量:

    // src/agent.js
    const API_ROOT = window.env.API_ROOT || 'https://api.realworld.io/api';
    
  3. 编写容器启动脚本替换占位符
    创建一个entrypoint.sh脚本,在容器启动时用环境变量替换index.html里的占位符:

    #!/bin/sh
    # 替换index.html中的API_ROOT占位符
    sed -i "s|%REACT_APP_API_ROOT%|${REACT_APP_API_ROOT:-https://api.realworld.io/api}|g" /usr/share/nginx/html/index.html
    # 启动nginx
    exec nginx -g "daemon off;"
    
  4. 更新Dockerfile使用启动脚本
    这个项目的生产构建是静态文件,用nginx托管,所以修改Dockerfile:

    FROM nginx:alpine
    # 复制构建产物到nginx目录
    COPY build /usr/share/nginx/html
    # 复制启动脚本
    COPY entrypoint.sh /entrypoint.sh
    # 赋予执行权限
    RUN chmod +x /entrypoint.sh
    # 设置启动入口
    ENTRYPOINT ["/entrypoint.sh"]
    
  5. 在OpenShift Deployment中配置环境变量
    为staging和live环境分别创建Deployment,设置对应的REACT_APP_API_ROOT:

    • staging环境的Deployment片段:
      spec:
        containers:
          - name: realworld-app
            image: your-registry/realworld-app:latest
            env:
              - name: REACT_APP_API_ROOT
                valueFrom:
                  configMapKeyRef:
                    name: realworld-api-config
                    key: staging_api_root
            ports:
              - containerPort: 80
      
    • live环境只需要把key换成live_api_root即可,用同一个镜像部署。

为什么方案二更贴合12factor?

  • 配置与代码完全分离:不需要修改代码或为不同环境构建镜像,同一个镜像可以在staging、live甚至本地运行
  • 动态调整:不需要重新构建,修改环境变量就能切换API地址,更灵活
  • 符合容器化最佳实践:镜像不可变,配置通过环境变量注入

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:03:33