IT이야기

도커가 설정한 반응 환경 변수 읽기

cyworld 2022. 3. 11. 22:29
반응형

도커가 설정한 반응 환경 변수 읽기

나는 대응 애플리케이션을 구축하여 nginx에 배치하기 위해 도커를 사용하고 있다.

docker-compose.yml에 환경 변수를 설정했다.

version: '2'
services:
  nginx:
    container_name: ui
    environment:
      - HOST_IP_ADDRESS= xxx.xxx.xx.xx
    build:
      context: nginx/
    ports:
      - "80:80"

도커 컨테이너가 생성된 후 나는 볼 수 있다.hi내가 할 때echo용기 내부의 변수

그러나, 내가 그것을 읽으려고 할 때, 나는 다음과 같이 반응한다.process.env.HOST_IP_ADDRESS그것은 벌목하고 있다.undefined.

어딘가의 블로그 포스트에서 환경변수는 생산환경에서만 접근할 수 있다는 글을 읽었다.앱을 만들고 nginx로 배포하고 있기 때문에 접속이 가능해야 하는데 왠지 읽을 수가 없다.

내가 여기서 근본적으로 잘못된 일을 하고 있는 것일까.그렇다면 나에게 해결 방법을 알려줘.나는 리액션 전문가가 아니라 다른 사람의 코드를 관리하는 것뿐이에요.

업데이트:

도커 파일은 다음과 같이 보인다.

FROM node:8 as ui-builder

WORKDIR /home/ui

COPY helloworld .

RUN npm install

RUN npm run build

FROM nginx
COPY --from=ui-builder /home/ui/build /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]

리액션 컴포넌트 조각은 다음과 같다.

import React, { Component } from 'react';

class HelloWorld extends Component {
  render() {
    console.log(process.env.HOST_IP_ADDRESS);
    return (
      <div className="helloContainer">
        <h1>Hello, world!</h1>
      </div>
    );
  }
}

export default HelloWorld;

답변과 댓글을 달아주신 모든 분들께 감사드린다.내가 직면하고 있던 문제는 이러한 해답과 다른 자원의 도움을 결합하여 해결되었다.

@DavidMaze(코멘트 중)가 제안한 대로, 나는 내 코드에 존재하는 웹팩 구성을 조사하기 시작했다.나는 웹팩이 컨테이너 안에 선언된 모든 환경변수를 읽고 있다는 것을 알게 되었다.

그래서 나는 내 Dockerfile과 Docker-compose.yml로 실험을 시작했다.REACT_APP_HOST_IP_ADDRESS환경변수로 전달되지 않고 있었는데, 그 반응은 코드를 만들고 있었다.

내가 가장 먼저 바꾼 것은 도커 파일이었다.테스트를 위해 도커 파일 내부의 IP를 정적으로 선언함
ENV REACT_APP_HOST_IP_ADDRESS localhost이를 통해 웹팩으로 읽혀지는 환경변수 안에서 localhost 값을 볼 수 있었다.

이제 나는 그의 대답에서 @Alex가 제안한 대로 ENV 변수를 도커-콤포즈에서 도커파일로 전달하려고 했지만 소용이 없었다.

그래서 나는 https://github.com/docker/compose/issues/5600을 참고하여 다음과 같이 Docker-document.yml과 Dockerfile을 변경하였다.

docker-present.yml

version: '2'
services:
  nginx:
    container_name: ui
    build:
      context: nginx/
      args:
        REACT_APP_HOST_IP_ADDRESS: ${IP_ADDRESS}
    ports:
      - "80:80"

어디에IP_ADDRESS주변 변수로 수출된다.

도커파일

FROM node:8 as ui-builder

WORKDIR /home/ui

COPY helloworld .

RUN npm install

ARG REACT_APP_HOST_IP_ADDRESS

ENV REACT_APP_HOST_IP_ADDRESS $REACT_APP_HOST_IP_ADDRESS

RUN npm run build

FROM nginx
COPY --from=ui-builder /home/ui/build /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]

리액션 컴포넌트

import React, { Component } from 'react';

class HelloWorld extends Component {
  render() {
    console.log(process.env.REACT_APP_HOST_IP_ADDRESS);
    return (
      <div className="helloContainer">
        <h1>Hello, world!</h1>
      </div>
    );
  }
}

export default HelloWorld;

이 구성은 이미지 빌드 프로세스 중에 도커-콤포즈에서 Dockerfile로 ARG를 통해 전달된 변수를 사용할 수 있게 하므로 웹 팩이 주변 변수를 읽을 경우 빌드 프로세스 중에 Reaction이 사용할 수 있는 주변 변수로 차례로 선언할 수 있다.

웹 팩은 DefinePlugin https://webpack.js.org/plugins/define-plugin/을 사용하여 환경 변수를 읽을 수 있을 것이다.

변수에 접두사를 붙이십시오.REACT_APP_(여기 보이는 바와 같이), 그렇지 않으면 리액션에 의해 픽업되지 않을 것이다.

환경변수는 RECT_APP_로 시작해야 한다. 그렇지 않으면 NODE_ENV 변수가 약간 혼동되어 환경변수가 작동하지 않는다.

environment:
  - REACT_APP_DEBUG=TRUE

그렇지 않으면docker-compose.yml유효하지 않고 다음과 같은 오류 메시지가 표시됨:

services.client.environment contains an invalid type, it should be an object, or an array

다음은 작업 샘플:

docker-present.yml

version: "3.3"

services:
  client:
    container_name: client
    environment:
      - REACT_APP_DEBUG=TRUE
    build:
      dockerfile: Dockerfile
      context: ./web/client

도커파일

FROM node:6.0.0

# Set env variable
ARG REACT_APP_DEBUG
ENV REACT_APP_DEBUG=$REACT_APP_DEBUG

# that will be empty
RUN echo "DEBUG": $REACT_APP_DEBUG

실행:

->docker-compose run  client node
->process.env.REACT_APP_DEBUG 
'TRUE'

당신은 다음 순간을 확인해야 한다.

I. 해당 변수에는 접두사가 있음 REACT_APP_

II. 도커 파일에는 다음과 같은 ARGENV 명령이 있다.

ARG REACT_APP_DEBUG
ENV REACT_APP_DEBUG=$REACT_APP_DEBUG

III. docker-compose.yml 에서 빌드 아그로 아그(arg)를 전달하면 마치

services:
  my-app:
    build:
      args:
        REACT_APP_DEBUG=True

도커 빌드에서는

docker build -t my_app:dev --build-arg REACT_APP_DEBUG=True .

API Platform에서 어떻게 하는지 확인했는데 config는 단지 env('env' 파일)을 기준으로 const를 정의한다.

export const API_HOST = process.env.REACT_APP_API_ENTRYPOINT;
export const API_PATH = '/';

값을 가져오는 동안 하나의 값(API_HOST)이 있음process.env.HOST_IP_ADDRESS런타임에 사용할 수 없는 깊은 개체 구조를 가리킨다.

다음은 다음 중 하나를 사용하여 해결 방법ENV나의DockerfileDefinePlugin에서webpack.config.js그리고process.env내 자바스크립트 코드로:

먼저 환경 변수 및 환경 변수 값을 다음으로 설정하십시오.

...
RUN npm install
ENV MY_ENV_VAR my_env_value
...

그 다음 사용DefinePlugin플러그인, 에 추가process.env:에

const webpack = require('webpack');
...
  plugins: [
    new webpack.DefinePlugin({
      'process.env.MY_ENV_VAR': JSON.stringify(env.MY_ENV_VAR),
    }),
  ],
...

마지막으로 코드에서 Environ 변수를 사용하십시오.

const host = process.env.MY_ENV_VAR || 'a_default_value_in_case_no_env_is_found';

나는 기투브 CI를 사용해 각 환경마다 비밀을 설정한다.처음 사용하는 GH 작업 파일run: docker build ... --build-arg REACT_APP_APIURL=${{ secrets.REACT_APP_APIURL }} .

그리고 나서 나는 그것들을 에 사용한다.Dockerfile다음과 같은 리액션 앱으로 최종 이미지를 작성하기 위한 리포:

ARG REACT_APP_APIURL
RUN test -n "$REACT_APP_APIURL" || (echo "REACT_APP_APIURL not set in GH/your environment" && false)
...
RUN npm run build

이 값은 에서 사용된다.npm run build에서 자작형 )process.env.REACT_APP_APIURL나는 이 값을 확인하고 내 도커 이미지나 구성에 문제가 있으면 앱이 로드될 때 즉시 실패하도록 선택했다.

export const config = {
  apiUrl: setApiUrlFromEnv(),
};
  
function setApiUrlFromEnv() {
  if (process.env.REACT_APP_APIURL) {
    return process.env.REACT_APP_APIURL;
  } else {
    // if something goes wrong in setup, do not start app and show err directly in web console
    throw new Error(
      `ENV not configured properly (REACT_APP_APIURL) to use desired ENV variables (${process.env.REACT_APP_APIURL})`
    );
  }
}

1단계: 도커-콤포즈 파일에 환경에 대한 아그 추가

빌드 스테이지에서는 환경 필드를 사용할 수 없기 때문에 환경 필드 대신 아그를 사용한다.

services:
    ...
    web_app:
        build:
          context: .
          dockerfile: Dockerfile
          args:
            - MY_ENV=HELLO_WORLD

1단계_대체:이미지가 docker-compose가 아닌 cloudbuild에 의해 작성되면 cloudbuild.yml 파일에 args를 추가해야 한다.

steps:
- name: ...
    args:
    ...
    - --build-arg
  - MY_ENV=HELLO_WORLD

단계: 2: 도커 파일에 ARGS 및 ENS 추가

Docker-compose args에서 변수를 가져오기 위해 ARG 명령을 사용한다.

ENV를 사용하여 구축 환경 설정

ARG MY_ENV

ENV MY_ENV=$MY_ENV

RUN echo "$MY_ENV"

3단계: 웹 팩 구성 업데이트

  • 웹 팩을 사용하십시오.웹 앱에서 프로세스를 활성화할 수 있도록 Plugin({ process: "process/browser" }) 제공
  • 웹 팩을 사용하십시오.웹 앱에서 사용할 수 있는 환경 변수를 정의하기 위한 DefinePlugin
  • npm i -S 프로세스별 dev 종속성에 프로세스 라이브러리 추가
plugins: [
    new webpack.ProvidePlugin({
      process: "process/browser"
    }),
    new webpack.DefinePlugin({ "process.env": JSON.stringify(process.env) })
  ]

참조URL: https://stackoverflow.com/questions/52103155/reading-an-environment-variable-in-react-which-was-set-by-docker

반응형