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

时间:2017-10-24 01:07:07

标签: 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:

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

console.log("process.env.REACT_APP_ENDPOINT")
console.log(process.env.REACT_APP_ENDPOINT)

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

运行docker-compose
docker swarm init 
docker stack deploy -c ~/webapp/docker-compose.yml webapp 

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

3 个答案:

答案 0 :(得分:1)

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

您将自己置于docker-compose.yml

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

具体而言,步骤#3。

答案 1 :(得分:0)

我注意到很多人都在努力解决这个问题,特别是如何在Dockerfile中传递ENV vars而不是条件脚本,所以我提供了一个简化的Github repo教程:

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

如果您愿意阅读,请参阅有关LinkedIn文章的公开文章:

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

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

此外,您需要在ENV变量前加REACT_APP_<yourvarname>前缀,并在您的应用中使用process.env.REACT_APP_SOMEVAR引用它们。

答案 2 :(得分:0)

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

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

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

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"]

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

docker build --build-arg REACT_APP_ENDPOINT=http://api.com -t front-server .

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

所以你的 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:

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

docker-compose up --build