DevOps/Docker

[따라하며 배우는 도커와 CI환경] 6. 간단한 어플을 실제로 배포해보기(개발 환경 부분)

wisdom11 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