如何通过docker-compose传递env_file重新构建create-react-app的Docker镜像
问题解决方案
核心原因:create-react-app 中以
REACT_APP_开头的环境变量是构建阶段静态注入到打包产物中的,Dockerfile 里的RUN yarn build-docker是镜像构建环节执行的,而 docker-compose 的env_file配置默认是容器运行阶段才会注入变量,因此镜像构建时无法读取到指定的环境变量配置。
方案一:通过 docker-compose 构建镜像时注入环境变量(匹配你的需求)
直接修改 docker-compose.yaml 配置,指定构建时加载对应 env 文件,每次启动前触发镜像构建即可:
- 修改
docker-compose.yaml中 app 服务的配置,将预构建镜像改为本地构建配置,同时指定构建阶段加载env文件:
app: container_name: app build: context: ./ # 此处替换为你的CRA项目根目录的相对路径 dockerfile: Dockerfile env_file: - env/app.env # 构建阶段就加载对应env文件,变量会传入构建上下文 restart: always
- 注意检查
env/app.env中的所有变量必须以REACT_APP_为前缀,否则 CRA 构建时会自动忽略该变量。 - 启动服务时添加
--build参数,触发app镜像重新构建:
docker-compose up -d --build app
构建阶段执行 yarn build-docker 时就会读取到 env/app.env 中的变量,注入到最终的打包产物中。
方案二:运行时动态注入环境变量(无需每次修改配置都重新构建镜像)
如果不想每次修改环境变量都重新构建镜像,可以采用运行时替换的方案:
- 在项目
public目录下新建config.js,占位符写法如下:
window.ENV = { REACT_APP_API_URL: '%REACT_APP_API_URL%', // 其他需要用到的环境变量都按这个格式列出来 }
- 在
public/index.html的<head>标签最顶部引入该配置文件:
<script src="%PUBLIC_URL%/config.js"></script>
- 项目代码中所有读取环境变量的位置,从
process.env.REACT_APP_XXX改为window.ENV.REACT_APP_XXX。 - 修改 Dockerfile 的启动入口,启动前先替换占位符再启动服务:
# 删掉原来的ENTRYPOINT,替换为以下内容 ENTRYPOINT ["/bin/sh", "-c", "sed -i 's|%REACT_APP_API_URL%|$REACT_APP_API_URL|g' /app/build/config.js && serve -s build"] # 有多个变量就多加几个sed替换命令即可
- 原有 docker-compose.yaml 配置不需要修改,env_file 配置的变量会在容器启动时注入,自动替换配置文件中的占位符,无需重新构建镜像。
内容的提问来源于stack exchange,提问作者maxleb
相关产品推荐
相关产品推荐

