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

React应用Docker镜像拉取后REACT_APP环境变量无法识别

React CI/CD构建镜像后运行时REACT_APP环境变量显示undefined的排查与解决

核心问题根源

React的REACT_APP_*前缀环境变量是在构建阶段(npm run build)由Webpack注入到静态文件中的,运行时(容器启动时)传入的环境变量对前端静态内容完全无效:

  • 本地构建时,你的.env文件在构建目录下,Webpack的dotenv插件自动读取并将变量编译进静态产物,所以即使容器运行时不传环境变量也能正常显示;
  • CI/CD构建时,没有在构建阶段传入这些环境变量,导致最终镜像里的静态文件根本没有注入这些变量。容器运行时传入的环境变量只能被Nginx进程读取,前端静态文件无法获取。

解决方案

方案1:CI构建阶段注入环境变量(推荐,适合固定环境的镜像)

通过GitHub Secrets存储敏感变量,在构建镜像时传入构建参数,让Webpack在构建阶段注入变量:

  1. 将环境变量存入GitHub Secrets
    在仓库的Settings > Secrets and variables > Actions中,添加以下Secrets:
    REACT_APP_URL、REACT_APP_API_URL、REACT_APP_VEHICLE_IMAGE_URL、REACT_APP_NAME,值对应你的.env内容。

  2. 修改GitHub Actions构建配置
    更新.github/workflows/docker-image.yml的构建步骤,添加构建参数:

- name: Build and push Docker image
  uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
  with:
    context: .
    push: true
    tags: dummy-frontend/test:latest
    build-args: |
      REACT_APP_URL=${{ secrets.REACT_APP_URL }}
      REACT_APP_API_URL=${{ secrets.REACT_APP_API_URL }}
      REACT_APP_VEHICLE_IMAGE_URL=${{ secrets.REACT_APP_VEHICLE_IMAGE_URL }}
      REACT_APP_NAME=${{ secrets.REACT_APP_NAME }}
  1. 修改Dockerfile接收构建参数
    在builder阶段添加ARG参数并转为环境变量,让Webpack能读取到:
FROM node:16-alpine as builder
WORKDIR /app

# 添加ARG接收构建参数
ARG REACT_APP_URL
ARG REACT_APP_API_URL
ARG REACT_APP_VEHICLE_IMAGE_URL
ARG REACT_APP_NAME

# 转换为环境变量,供Webpack构建时注入
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

COPY . .
RUN npm ci 
RUN npm run build

# production阶段内容不变
FROM nginx:1.21.0-alpine as production
ENV NODE_ENV production
COPY --from=builder /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

完成后,CI构建的镜像会直接包含注入好变量的静态文件,拉取后直接运行即可,无需再传--env-file。


方案2:运行时注入环境变量(适合多环境复用同一镜像)

如果需要同一个镜像在不同环境使用不同变量,可以通过启动脚本动态替换静态文件中的变量占位符:

  1. 创建环境变量模板文件
    在项目public目录下新建env.js:
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%"
};
  1. 在index.html中引入模板
    修改public/index.html的<head>部分:
<script src="%PUBLIC_URL%/env.js"></script>
  1. 修改代码读取window.env
    将原来读取process.env的代码改为读取window.env:
{window.env.REACT_APP_NAME == null ? "undefined" : window.env.REACT_APP_NAME}
  1. 添加启动脚本并修改Dockerfile
  • 项目根目录新建entrypoint.sh:
#!/bin/sh

# 替换env.js中的占位符为容器环境变量
sed -i "s/%REACT_APP_URL%/$REACT_APP_URL/g" /usr/share/nginx/html/env.js
sed -i "s/%REACT_APP_API_URL%/$REACT_APP_API_URL/g" /usr/share/nginx/html/env.js
sed -i "s/%REACT_APP_VEHICLE_IMAGE_URL%/$REACT_APP_VEHICLE_IMAGE_URL/g" /usr/share/nginx/html/env.js
sed -i "s/%REACT_APP_NAME%/$REACT_APP_NAME/g" /usr/share/nginx/html/env.js

# 执行原Nginx启动命令
exec "$@"
  • 修改Dockerfile的production阶段:
FROM nginx:1.21.0-alpine as production
ENV NODE_ENV production
COPY --from=builder /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
# 复制启动脚本并赋予执行权限
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
EXPOSE 80
ENTRYPOINT ["/entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]

完成后,拉取镜像用原来的docker run --env-file .env命令启动,脚本会自动将容器环境变量替换到静态文件中,前端即可读取。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 00:05:04