Docker Compose watch: 소스 변경 자동 감지 핫 리로드

compose watch의 sync·rebuild·sync+restart 세 가지 action, develop.watch 블록 설정법, Node.js·Python 핫 리로드 실전 패턴을 정리합니다.

· 4 min read · PALDYN Team

지난 글에서 override 파일로 개발 환경을 분리하는 방법을 살펴봤다. 이번에는 Compose v2.22에서 GA된 watch 기능으로 소스 파일 변경을 자동으로 감지해 컨테이너에 반영하는 방법을 정리한다.

compose watch가 해결하는 문제

볼륨 바인드 마운트(. :/app)는 컨테이너와 호스트 파일시스템을 공유하는 가장 단순한 방법이지만, 노드 모듈처럼 컨테이너 안에서만 필요한 디렉터리를 덮어쓰거나 성능 문제(macOS)가 있다. watch어떤 파일이 바뀌면 어떤 동작을 할지 선언적으로 제어한다.

services:
  web:
    build: .
    develop:
      watch:
        - action: sync
          path: ./src
          target: /app/src
        - action: rebuild
          path: package.json

action 타입 세 가지

sync — 파일을 컨테이너 target 경로로 즉시 복사한다. 컨테이너가 재시작되지 않는다. 앱 내부의 핫 리로더(nodemon, uvicorn --reload)가 변경을 감지해서 처리한다.

rebuild — 이미지를 재빌드하고 컨테이너를 교체한다. Dockerfile 변경이나 의존성 파일(package.json, requirements.txt, go.sum) 변경 시 쓴다. 시간이 걸리지만 완전히 새 환경으로 시작한다.

sync+restart — 파일을 sync한 뒤 컨테이너만 재시작한다. 이미지 재빌드 없이 빠르게 설정 파일 변경을 반영할 때 쓴다.

compose watch 동작 다이어그램

언제 어떤 action을 쓰나

변경 파일권장 action
소스 코드 (핫리로더 있음)sync
Dockerfile, .dockerignorerebuild
package.json, requirements.txtrebuild
nginx.conf, app.yaml 등 설정sync+restart
정적 파일 (CSS, 이미지)sync

Node.js와 Python 예시

services:
  # Node.js — nodemon으로 핫 리로드
  web:
    build: .
    command: npx nodemon src/index.js
    develop:
      watch:
        - action: sync
          path: ./src
          target: /app/src
        - action: rebuild
          path: package.json

  # Python — uvicorn --reload
  api:
    build: .
    command: uvicorn app.main:app --reload --host 0.0.0.0
    develop:
      watch:
        - action: sync
          path: ./app
          target: /app
          ignore:
            - __pycache__
            - "*.pyc"
        - action: rebuild
          path: requirements.txt

compose watch 코드 예시

watch 실행 방법

# watch 모드로 시작
docker compose up --watch

# 이미 실행 중일 때 watch 시작
docker compose watch

# 특정 서비스만
docker compose watch web api

ignore 패턴

path 아래에서 감시할 때 제외할 패턴을 ignore로 지정한다. glob 형식이다.

- action: sync
  path: .
  target: /app
  ignore:
    - node_modules/
    - "*.test.ts"
    - dist/
    - .git/

node_modules, .git, pycache 같은 공통 패턴은 자동으로 제외된다.

볼륨 마운트 vs watch 비교

기준bind mountcompose watch
선언volumes: .:/appdevelop.watch
세밀한 제어어려움파일별 action 지정
node_modules 충돌anonymous volume으로 해결자연스럽게 분리
macOS 성능느림 (옵션으로 개선 가능)sync만 하므로 빠름
멀티 action불가sync+rebuild 조합 가능

소규모 프로젝트에서는 bind mount가 간단하고 충분하다. 더 정교한 제어가 필요하거나 macOS에서 성능 문제가 있을 때 watch로 전환한다.


지난 글: Docker Compose override: 환경별 설정 재정의 패턴

다음 글: Docker Compose up/down: 서비스 생명주기 완전 정복


읽어주셔서 감사합니다. 😊