Create-React-App 不从 docker-compose.yml 读取环境变量

irr*_*lar 9 reactjs docker-compose

version: "3"
services:
  web:
    # replace username/repo:tag with your name and image details
    image: user1/webapp:latest
    volumes:
      - ./local-db:/go/src/webapp/local-db
    environment:
      - REACT_APP_ENDPOINT=http://api.com
    deploy:
      replicas: 5
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
      restart_policy:
        condition: on-failure
    ports:
      - "8080:8080"
    networks:
      - webnet
networks:
  webnet:
Run Code Online (Sandbox Code Playgroud)

webapp 是为 create-react-app 提供服务的服务器,但是当我运行时

console.log("process.env.REACT_APP_ENDPOINT")
console.log(process.env.REACT_APP_ENDPOINT)
Run Code Online (Sandbox Code Playgroud)

根据https://daveceddia.com/multiple-environments-with-react/ 我应该能够访问环境变量。我运行 docker-compose 使用

docker swarm init 
docker stack deploy -c ~/webapp/docker-compose.yml webapp 
Run Code Online (Sandbox Code Playgroud)

控制台日志打印,undefined但如果我在没有 docker 的本地机器上运行服务 create-react-app 的服务器,前端会正确打印环境变量。

Mik*_* S. 5

我注意到很多人都在为此苦苦挣扎,尤其是如何在 Dockerfile 中传递 ENV 变量而不是条件脚本,所以我提供了一个简化的 Github repo 教程:

 - https://github.com/mikesparr/tutorial-react-docker

如果您愿意阅读,可以通过 LinkedIn 文章上的公开文章了解背景:

 - https://www.linkedin.com/pulse/dockerizing-your-react-app-mike-sparr/


简而言之,您需要 DockerfileCMD来运行执行buildserver start步骤的脚本,以便应用程序可以使用运行时容器配置。

此外,您需要REACT_APP_<yourvarname>在您的应用程序中为您的 ENV 变量添加前缀,并使用process.env.REACT_APP_SOMEVAR.


Bey*_*Sea 5

Create-react-app 更喜欢有一个 .env 文件,以便将您的环境变量嵌入到构建中。

显然,对 .env 文件进行版本控制并不是一个好的做法,create-react-app 官方文档违背了12 -factor-app 理念。

所以让我们使用干净的解决方案!最简单的方法是在 Dockerfile 构建环境中动态创建 .env 文件:

为此创建一个简单的脚本create-env-file.sh

touch .env

for envvar in "$@" 
do
   echo "$envvar" >> .env
done
Run Code Online (Sandbox Code Playgroud)

它将复制您传递给新的 .env 文件的每个参数

RUN npm run build然后在 Dockerfile 中调用它:

FROM node:14-alpine

WORKDIR /app

COPY src/ ./src/
COPY public/ ./public/
COPY pack*.json ./
COPY tsconfig.json .
COPY create-env-file.sh ./create-env-file.sh

RUN npm i

# Add as many arguments as you want to pass environment variables 
#   and use an ARG command for each one, so Dockerfile context will grab it from --build-arg

ARG REACT_APP_ENDPOINT

RUN sh create-env-file.sh REACT_APP_ENDPOINT=$REACT_APP_ENDPOINT

# If you want to debug the .env file, uncomment the following line
# CMD ["cat", ".env"]

RUN npm run build

RUN npm i -g serve

EXPOSE 5000

CMD ["serve", "-s", "build"]
Run Code Online (Sandbox Code Playgroud)

然后使用--build-arg将您的环境变量传递给 docker build 命令:

docker build --build-arg REACT_APP_ENDPOINT=http://api.com -t front-server .
Run Code Online (Sandbox Code Playgroud)

您必须使用 ARG 命令引用每个传递的构建参数,因为 docker build 将构建参数视为参数而不是环境变量。看这里

所以你的 docker-compose.yml 看起来像这样:

version: "3"
services:
  web:
    build:
      context: .
      args:
        REACT_APP_ENDPOINT=http://api.com
    image: user1/webapp:latest
    volumes:
      - ./local-db:/go/src/webapp/local-db
    deploy:
      replicas: 5
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
      restart_policy:
        condition: on-failure
    ports:
      - "8080:8080"
    networks:
      - webnet
networks:
  webnet:
Run Code Online (Sandbox Code Playgroud)

--build与 docker-compose up 一起使用:

docker-compose up --build
Run Code Online (Sandbox Code Playgroud)


pat*_*ick 1

Create React App 支持 .env 文件,这意味着您可以将永久环境变量放入这些文件之一中,以使其可供应用程序使用。

你正在把你的放在你的docker-compose.yml.

这里找到了一个处理此问题的解决方案: https://github.com/facebookincubator/create-react-app/issues/982#issuecomment-273032553

具体来说,步骤#3。