ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [따라하며 배우는 도커와 CI환경] 6. 간단한 어플을 실제로 배포해보기(개발 환경 부분)
    DevOps/Docker 2022. 5. 30. 14:56

     

    이번 시간부터는 간단한 애플리케이션를 배포하면서 도커를 배워보자.

     

    ✔️ 리액트 환경 세팅

    리액트를 사용하려면 node를 반드시 설치해야 한다. 

    $ npx create-react-app ./

    node 설치 후, 위의 명령어를 통해 리액트 앱을 위한 환경을 세팅한다.
    명령어가 실행되면 다음과 같은 파일들이 생성된다.

     

     

    ✔️ 도커로 리액트 앱 실행

    이제 도커를 통해 리액트 앱을 실행해보자.

    도커로 리액트 앱을 실행하기 위해서는 다음과 같은 과정을 수행해야 한다.

     

    1️⃣  도커 파일 생성 및 빌드

    다음과 같이 도커 파일을 생성하자.

    Dockerfile.dev

    FROM node:alpine

    WORKDIR /usr/src/app

    COPY package.json ./

    RUN npm install

    COPY ./ ./

    CMD ["npm", "run", "start"]

     

    이제 도커 파일을 통해 이미지를 생성해야 한다. 다음의 명령어를 통해 빌드하자.

    $ docker build -f Dockerfile.dev -t [이미지 이름] ./

    ❗️ 도커 파일의 이름이 Dockerfile일 경우에는 파일 이름을 명시하지 않아도 되지만, Dockerfile.dev 라는 이름으로 만들었기 때문에 -f 옵션을 통해 파일 이름을 지정해주었다.

     

     

    📌  팁! 로컬에 있는 node_modules는 지워주자.
    이미지를 빌드할 때 이미 npm install로 모든 모듈들을 도커 이미지에 다운받기 때문에, 로컬 머신에 node_modules가 필요없다.
    또한, COPY ./ ./  를 통해 파일을 복사할 때 node_modules가 복사된다. 이미 npm install로 생성하였는데 불필요하게 한 번 더 복사가 되므로 로컬에 있는 node_modules는 지우도록 하자.

     

     

    2️⃣  도커 이미지로 리액트 앱 실행

    $ docker run -p 3000:3000 [이미지 이름]

    위의 명령어를 통해 도커 컨테이너를 생성하고 실행할 수 있다.
    리액트는 기본적으로 3000 포트를 사용하기 때문에 3000번으로 포트 매핑을 해주었다.

     

    이렇게 실행해주면, create-react-app 을 통해 생성된 기본적인 리액트 앱이 잘 실행되는 것을 확인할 수 있다.

     

    3️⃣  도커 볼륨 사용

    이제 COPY 대신 Volume을 사용해서 소스 코드 변경 시 재빌드하지 않아도 적용이 되도록 해보자!

    $ docker run -p 3000:3000 -v /usr/src/app/node_modules -v $(pwd):/usr/src/app [이미지 이름]

    위의 명령어에 대한 설명은 이전 포스트에서 설명했다.

     

    /src/App.js 을 다음과 같이 변경 후, 빌드하지 않고 바로 변경된 부분이 적용된다.

    import logo from './logo.svg';
    import './App.css';
    
    function App() {
      return (
        <div className="App">
          <header className="App-header">
            <img src={logo} className="App-logo" alt="logo" />
            <p>
              Edit <code>src/App.js</code> and save to reload.
            </p>
            <a
              className="App-link"
              href="https://reactjs.org"
              target="_blank"
              rel="noopener noreferrer"
            >
              안녕하세요!  <!-- Learn React 에서 변경됨 -->
            </a>
          </header>
        </div>
      );
    }
    
    export default App;

     

    docker run -p 3000:3000 -v /usr/src/app/node_modules -v $(pwd):/usr/src/app [이미지 이름]

    간편하긴 하지만 명령어가 너무 길다...
    간단하게 실행할 수 있는 방법을 알아보자.

     

    4️⃣  도커 컴포즈로 실행

    지난 포스트에서 도커 컴포즈(Docker Compose)를 통해 , 컨테이너로 된 서비스에 대한 실행 옵션을 지정해줄 수 있었다.
    이렇게 미리 옵션들을 정의하면 실행 시 간단한 명령어를 통해 컨테이너를 실행할 수 있다.

    docker-compose.yml 파일을 다음과 같이 작성하자.

    version: "3"
    services:
      react:
        build:
          context: .
          dockerfile: Dockerfile.dev
        ports:
          - "3000:3000"
        volumes:
          - /usr/src/app/node_modules
          - ./:/usr/src/app
        stdin_open: true


    각 옵션의 의미는 다음과 같다.

     

    이제 도커 컴포즈를 통해 앱을 실행하자.

    $ docker-compose up

    잘 실행되는 것을 확인할 수 있다.

     

    5️⃣  리액트 앱 테스트

    이제 도커 환경에서 리액트 앱을 테스트해보자.

    $ docker run [이미지 이름] npm run test

    기본적으로 위의 명령어를 통해 리액트 앱을 테스트할 수 있다.
    그러나 이렇게 실행하게 되면, 위에서 도커 볼륨을 사용하기 전에 그랬듯이 테스트 코드에 대한 변경사항이 자동으로 반영되지 않는다.

    테스트 소스 코드 변경 시 변경 사항이 바로 적용이 되도록, docker-compose.yml 파일을 수정하자.

    version: "3"
    services:
      react:
        build:
          context: .
          dockerfile: Dockerfile.dev
        ports:
          - "3000:3000"
        volumes:
          - /usr/src/app/node_modules
          - ./:/usr/src/app
        stdin_open: true
    
      # 추가된 부분
      tests:
        build:
          context: .
          dockerfile: Dockerfile.dev
        volumes:
          - /usr/src/app/node_modules
          - ./:/usr/src/app
        command: ["npm", "run", "test"]

     

    이제 다음과 같이 앱을 실행하자.

    $ docker-compose up --build

    실행하면 리액트 앱과 테스트가 모두 실행되는 것을 확인할 수 있다.

    이제 /src/App.test.js 를 수정하면 바로 테스트에 적용된다!

     

    ✔️ 운영환경을 위한 Nginx 사용

    지금까지 개발환경에서 리액트 앱을 실행하였다.
    이제 도커를 사용해서 운영환경에서 리액트를 실행해보자. 

    다음은 운영환경에서 앱을 실행하는 과정이다.

    운영환경에서는 개발서버가 아닌 Nginx 서버를 사용한다.

    Nginx 는  동시접속 처리에 특화된 웹 서버 프로그램으로, 요청에 응답하기 위해 비동기 이벤트 기반 구조를 가진다. 


    개발 서버에 존재하는 개발에 특화된 기능은 운영 서버에 불필요하고 속도를 늦출 수 있기 때문에 운영 서버를 따로 둔다.

     

    1️⃣  도커 파일 생성

    개발 환경에서는 build를 하지 않고도 실행할 수 있지만, 운영 환경에서는 build를 반드시 해줘야 한다.
    도커 파일의 구조는 다음과 같은 차이가 있다.

     

    운영 환경에서의 도커 파일의 구조를 더 자세하게 살펴보자.
    이것은 2가지 Stage로 나눌 수 있는데, Builder Stage와 Run Stage 이다.

     

    📌 Builder Stage

    빌드 파일을 생성하기 위한 stage.
    리액트에서는 npm run build를 통해 빌드 파일을 생성한다.

    📌 Run Stage

    Nginx를 실행하여 웹 브라우저 요청에 따라 정적 파일을 제공해주는 stage.
    빌드된 파일을 이용한다.

     

    다음과 같이 도커 파일을 작성하자.

    Dockerfile 파일

    # Builder Stage
    FROM node:alpine as builder
    WORKDIR /usr/src/app
    COPY package.json ./
    RUN npm install
    COPY ./ ./
    CMD ["npm", "run", "build"]

    # Run stage
    FROM nginx
    COPY --from=builder /usr/src/app/build /usr/share/nginx/html

     

    2️⃣  도커 이미지 빌드 및 실행

    $ docker build -t [이미지 이름] ./

    위의 명령어를 통해 도커 이미지를 빌드한다. 
    이번에는 도커 파일 이름이 Dockerfile 이므로 파일 이름을 따로 지정해줄 필요는 없다.

     

    $ docker run -p 8080:80 [이미지 이름]

    Nginx 의 기본 포트 번호는 80번이다.
    위의 명령어를 통해, 로컬 포트 8080번과 컨테이너 포트 80번을 매핑하여 컨테이너를 실행할 수 있다.

     

    localhost:8080 으로 잘 실행되는 것을 확인할 수 있다!

     

     

     

    참고

     

     

     

    728x90

    댓글

Designed by Tistory.