Server || Infra/Docker

[Docker] React, 격리환경 구성과 핫 리로딩(hot reloding)

기록하는 습관. 2025. 1. 18. 05:06

팀에서 Docker를 사용하면 운영체제와 상관없이 일관성있는 개발환경을 유지할 수 있습니다.
이번 포스팅에서는 로컬 환경 React코드가 실시간으로 반영(핫리로드)되는 Docker 격리환경(빌드환경) 구성을 목표로 합니다.


STEP 1. Dockerfile

Docker는 Dockerfile을 기반으로 이미지를 생성하고, 이 이미지를 Docker 컨테이너로 실행하는 흐름을 갖습니다.** 하나의 도커 이미지로 여러 개의 도커 컨테이너를 만들 수 있고, 각각의 컨테이너는 독립적으로 실행됩니다.


  • Dockerfile
FROM node:18

# Set working directory
WORKDIR /app

# Install dependencies
COPY package*.json ./
RUN npm install

# Copy all files
COPY . .

# Expose port
EXPOSE 3000

# Start the application
CMD ["npm", "start"]

첫번째로 저는 CRA로 React프로젝트를 생성하고 프로젝트 루트에 Dockerfile을 작성해주었습니다.


FROM은 베이스 이미지를 지정합니다. 베이스 이미지란 애플리케이션 실행 환경을 제공합니다.
WROKDIR는 컨테이너 내에서 작업 디렉토리를 설정하는 명령어입니다. 즉, 파일들이 저장될 위치를 지정합니다.
COPY는 호스트 컴퓨터에 있는 파일을 컨테이너 작업 디렉터리로 복사하는 명령어입니다.
RUN npm install은 컨테이너에 의존성 라이브러리를 설치하는 명령어입니다.
EXPOSE는 컨테이너 내부에서 특정 포트를 열어주는 명령어로 설정 포트를 통해 요청을 수신합니다.
CMD는 컨테이너 실행될 때 실행할 명령을 지정합니다.



STEP 2. docker-compose.yml

Docker compose는 아래와 같은 이유로 필요합니다.

  • 여러개의 Docker 컨테이너를 정의하고 관리
    • 예를 들어 백엔드, 프론트엔드, 데이터베이스의 각각의 컨테이너가 필요할 수 있는데 Docker Compose 도구를 이용하면 한 번에 실행하고 관리할 수 있습니다.
  • 각각의 컨테이너 간 네트워킹
    • 각각의 컨테이너들은 Docker compose가 자동으로 네트워크를 설정하여 통신할 수 있도록 해줍니다.
  • 간단한 설정
    • 복잡한 명령어 없이 하나의 설정 파일에 모든 구성을 작성하고 실행할 수 있습니다.
  • 환경변수 관리
    • .env파일을 사용해 환경 변수도 쉽게 관리할 수 있습니다.

이번 Docker compse를 작성하는 목적은 핫 리로딩(hot reloding)을 사용하는데 의의를 둡니다.
핫 리로딩이란, 로컬 환경의 소스 코드가 변경되었을 때 이를 컨테이너가 실시간으로 반영하는 것을 의미합니다.


  • docker-compose.yml
# 서비스로 실행하려는 컨테이너를 정의
services: 
  # 나의 프로젝트 이름, 보통은 app으로 적어주지만 
  # 여러 컨테이너를 사용할 수 있는 여지가 있어 식별하기 위해 식별할 수 있는 고유 이름으로 지정
  dev-hiresetup-web:
    # 빌드할 Dockerfile 관련 설정
    build:
      context: . # Dockerfile의 위치
      dockerfile: Dockerfile # 찾을 Dockerfile의 이름
    # Dockerfile 빌드 대상 이미지 이름 설정
    image: hiresetup-web:latest
    # 마운트 설정 
    volumes:
      - .:/dev-hiresetup-web 
      #⬆️호스트 바인드 마운트
      # 호스트의 현재 디렉토리를 컨테이너의 /hiresetup-web으로 마운트함을 의미함
      # 이는 컨테이너 내부의 /hiresetup-web 디렉토리에 호스트의 모든 파일을 덮어                         # 씌우게 됌
      - /dev-hiresetup-web/node_modules 
      # ⬆️익명 볼륨 (볼륨이란, 저장소로 이해해도 좋다)
      # 컨테이너 내부 /dev-hiresetup-web/node_modules 경로의 파일을 익명의 볼륨으로 관리한다.
      # 익명의 볼륨은 호스트 파일과 상관없이 Docker가 독립적으로 관리한다. 
      # 설정의 필요성은 컨테이너 내부에서만 필요한 파일을 독립적으로 관리할 때 사용한다. 
      # 사실 개발환경에서는 호스트 바인드 마운트로 사용하는 것이 효율적이다.
      # 만약, 해당 설정을 하고 오류없이 사용하려면 컨테이너에 접속하여 npm install을 해주어야한다.
      # 명심하자. 익명 볼륨과 호스트의 해당 파일은 분리되어 있고 설정시 컨테이너는 익명볼륨을 바라본다.

    ports:
      - "3000:3000" # 호스트 3000번 포트로 컨테이너 3000번 포트에 접속한다.
    environment:
      - WATCHPACK_POLLING=true # window에서 핫 리로딩(hot reloding)을 동작시키기 위해 설정한다.
    command: [ "npm", "start" ] # 컨테이너 실행 후, 명령어를 실행한다.

설명은 주석으로 대체합니다.

해당 설정이 완료되었으면 docker-compose up --build로 Docker Compose를 실행합니다.



수정사항

[1] 2025-01-19. Dockerfile

FROM node:18

# Set working directory
WORKDIR /app

# Install dependencies
COPY package*.json ./
RUN npm install

# Copy all files
COPY . .

# Expose port
EXPOSE 3000

# Start the application
CMD ["npm", "start"]

기존 Dockerfile입니다. 여기서 WORKDIR /app을 WORKDIR /dev-hiresetup-web-app로 바꿔주었습니다.
바꾼 이유는, 컨테이너 내부에서 /app 디렉토리를 바라보는 것이 아니라, /dev-hiresetup-web-app을 바라보게 설정합니다. 이를 바꿔주지 않으면 핫리로딩이 동작하지 않습니다.