본문 바로가기

javascript/이외

[nest.js & docker] window 환경에서 nest.js에 volume을 연결했지만 동작하지 않는 경우

결론

typescript 4.9 버전 정도부터 감시 옵션이 파일 시스템 기반 감시를 수행하도록 구성되어 있으나, window 환경에서 volume을 지정하면 해당 옵션이 제대로 동작하지 않는 듯 하다. tsconfig.json 파일에 다음 옵션을 추가해보자.

  "watchOptions": {
    "watchFile": "fixedPollingInterval"
  }

최신 버전의 nest.js을 사용하고 있다. docker-compose.yml 파일을 다음과 같이 작성했다.

version: '3'
services:
  backend:
    ports:
      - 8080:8080
    depends_on:
      - my-redis # redis 동작해야 의미 O
    build:
      context: ./server
      dockerfile: Dockerfile.dev
    env_file:
      - "./server/.env"
    volumes:
      - /home/app/node_modules
      - ./server:/home/app
    deploy:
      restart_policy:
        condition: on-failure
        delay: 3s
        max_attempts: 3
  my-redis:
    image: redis:alpine

참고로 Dockerfile은 다음과 같다.

FROM node:alpine

# 작업 폴더 생성
RUN mkdir /home/app
# 작업 폴더 지정
WORKDIR /home/app

# port 8080으로 외부 데이터 들을 수 있음
EXPOSE 8080

# 설정 파일들 복사
COPY package*.json .

# 의존성 설치
RUN npm ci
# 나머지 파일들 복사
COPY . .

# 실행 시 보여줄 명령
CMD ["npm", "run", "start:dev"]
# ENTRYPOINT ["tail", "-f", "/dev/null"]

여기서 문제는 volume이 동작함에도 불구하고 reload를 수행하지 않는다는 점이다. docker exec 을 이용하여 파일의 변화를 체크했을 때 정상적으로 변경사항이 반영됨을 알 수 있었다.

정보를 찾다보니 공식 깃허브에 나와 비슷한 현상을 겪는 사람이 있었다.

https://github.com/nestjs/nest/issues/11615

 

Hot reloading on file changes in docker not working with nest-cli.json generate library - Window · Issue #11615 · nestjs/nest

Is there an existing issue for this? I have searched the existing issues Current behavior Hot reloading on file changes in docker not working with nest-cli.json - Window Minimum reproduction code n...

github.com

typescript 4.9 버전으로 업데이트 되면서 감시의 기본값이 지속적으로 상태를 검사하는 polling 방식에서 파일 시스템 기반으로 변경되면서 감시 성능이 높아졌다고 한다.

그런데, 해당 변경점이 들어오면서 window 환경에서 개발하고 docker volume을 이용하면 이상하게도 무한히 reload되거나 아예 인식하지 못하는 문제가 생겼다고 한다. nest.js 공식문서에서도 해당 내용에 대해 설명하고 있었다.

현재 시점에서 해결 방법은 파일 감시 방식을 기존으로 돌리는 것이다.

{
  "compilerOptions": {
  // 옵션들
  },
  "watchOptions": {
    "watchFile": "fixedPollingInterval"
  }
}

4.9 버전 기준 기본 값은 useFsEvents로, 운영체제 및 파일 시스템의 기본 이벤트를 이용하는 방식이다. 이를 polling 방식으로 변경하면 문제가 해결된다. 댓글 중 wsl 환경에서 프로그램을 작성하면 문제가 발생하지 않는다고 하는 것을 보면 window와 wsl 환경이 다른 파일 시스템을 사용해서 발생하는 문제가 아닌가 싶다.