티스토리 뷰
Docker Compose Watch는 개발 중 파일을 저장할 때 컨테이너에 변경 사항을 자동 반영하는 기능입니다. 핵심은 compose.yaml의 서비스 아래에 develop.watch 규칙을 추가하고, docker compose up --watch 또는 docker compose watch로 실행하는 것입니다. 소스 코드는 sync, 의존성 파일은 rebuild, 설정 파일은 sync+restart로 나누면 불필요한 재빌드를 줄이고 개발 피드백 속도를 높일 수 있습니다. 이 글은 로컬 개발 환경에서 Docker를 쓰지만 매번 build, up, restart를 반복하는 분에게 유용합니다.
검색 의도: 이 주제는 정보형 의도가 가장 강합니다. 따라서 개념 설명보다 바로 적용 가능한 설정 예시, 액션별 차이, 문제 해결 체크리스트를 중심으로 구성했습니다.
Docker Compose Watch란 무엇인가
Docker Compose Watch는 호스트의 파일 변경을 감지해 실행 중인 Compose 서비스에 자동으로 반영하는 개발용 기능입니다. 기존에는 코드를 수정한 뒤 컨테이너 내부에 반영하려면 bind mount를 쓰거나, docker compose build && docker compose up을 반복해야 했습니다. Watch를 사용하면 어떤 파일은 컨테이너로 동기화하고, 어떤 파일은 이미지를 다시 빌드하며, 어떤 파일은 동기화 후 컨테이너를 재시작하도록 세밀하게 제어할 수 있습니다.
공식 문서 기준으로 Watch는 develop.watch 아래에 여러 규칙을 선언하는 방식입니다. 각 규칙은 주로 path, action, 필요 시 target, ignore, include, initial_sync 같은 속성을 사용합니다. 예를 들어 프론트엔드의 src/ 변경은 sync로 빠르게 반영하고, package.json 변경은 의존성 설치가 필요하므로 rebuild로 처리하는 식입니다.
간단히 말하면 Watch는 개발 환경 자동 반영 레이어입니다. 운영 배포를 위한 기능이라기보다, 로컬에서 컨테이너 기반 개발을 할 때 저장과 반영 사이의 반복 작업을 줄이는 도구에 가깝습니다.
| 방식 | 특징 | 적합한 상황 |
|---|---|---|
| bind mount | 호스트 디렉터리를 컨테이너에 직접 연결 | 단순 개발, 즉시 파일 공유 |
| Compose Watch | 변경 감지 후 규칙에 따라 sync/rebuild/restart | 복잡한 프로젝트, OS 차이, 의존성 제외 필요 |
| 수동 rebuild | 명령어를 직접 반복 | 변경 빈도가 낮은 프로젝트 |
Docker Compose Watch 사용법: 기본 설정
가장 기본적인 Docker Compose Watch 사용법은 compose.yaml에 develop.watch를 추가하는 것입니다. 다음 예시는 Node.js 또는 Vite 기반 프론트엔드 프로젝트에서 자주 쓰는 패턴입니다.
services:
web:
build: .
command: npm run dev
ports:
- "5173:5173"
develop:
watch:
- action: sync
path: ./src
target: /app/src
initial_sync: true
ignore:
- node_modules/
- action: rebuild
path: package.json
실행은 다음 중 하나를 사용합니다.
docker compose up --watch
또는 애플리케이션 로그와 Watch 이벤트를 분리하고 싶다면 다음 명령을 사용할 수 있습니다.
docker compose watch
docker compose up --watch는 서비스를 올리면서 Watch 모드를 함께 시작합니다. 반면 docker compose watch는 Watch에 집중한 명령이며, 옵션으로 --no-up, --quiet, --prune 등을 사용할 수 있습니다. 이미 서비스를 띄워둔 상태에서 파일 감시만 별도로 보고 싶다면 후자가 더 깔끔합니다.
주의할 점은 Compose Watch가 주로 build 속성으로 로컬 소스에서 이미지를 만드는 서비스에 맞춰 설계되어 있다는 점입니다. 단순히 image: nginx:latest처럼 미리 빌드된 이미지만 사용하는 서비스라면 Watch가 기대한 대로 동작하지 않을 수 있습니다.
Docker Compose Watch action 차이: sync, rebuild, restart
Docker Compose Watch의 핵심은 action 선택입니다. 같은 파일 변경이라도 어떤 액션을 쓰느냐에 따라 개발 속도와 정확성이 크게 달라집니다.
| action | 동작 | 추천 대상 |
|---|---|---|
sync |
호스트 파일을 컨테이너의 target 경로로 동기화 |
React, Vue, Next.js, Flask 코드 |
rebuild |
이미지를 다시 빌드하고 컨테이너 재생성 | package.json, requirements.txt, Dockerfile 영향 파일 |
sync+restart |
파일 동기화 후 컨테이너 재시작 | nginx.conf, 앱 설정 파일 |
restart |
컨테이너만 재시작 | 재시작만 필요한 경우, Compose 2.32.0 이상 |
sync+exec |
동기화 후 컨테이너 안에서 명령 실행 | reload 명령이 있는 서버, Compose 2.32.2 이상 |
가장 많이 쓰는 조합은 sync와 rebuild입니다. 예를 들어 src/App.tsx를 수정할 때마다 이미지를 다시 빌드하면 개발 흐름이 느려집니다. 이 경우 sync로 파일만 컨테이너에 복사하고, 컨테이너 내부의 Vite나 Webpack 같은 개발 서버가 Hot Reload를 처리하게 하는 편이 효율적입니다.
반대로 package.json, pnpm-lock.yaml, requirements.txt, go.mod 같은 파일은 단순 파일 복사만으로 충분하지 않을 수 있습니다. 의존성 설치, 빌드 캐시, 실행 환경 자체가 바뀌기 때문입니다. 이런 파일은 rebuild로 처리해야 컨테이너 상태가 실제 개발 환경과 어긋나지 않습니다.
설정 파일은 중간 지점에 있습니다. 예를 들어 nginx.conf는 이미지를 다시 빌드하지 않아도 되지만, 프로세스가 설정을 다시 읽어야 합니다. 이때 sync+restart가 적합합니다.
Docker Compose Watch 예제: 프론트엔드와 백엔드 구성
실제 프로젝트에서는 프론트엔드, 백엔드, 프록시가 함께 움직이는 경우가 많습니다. 다음은 Vite 프론트엔드와 Express 백엔드를 단순화한 예시입니다.
services:
frontend:
build:
context: ./frontend
command: npm run dev -- --host 0.0.0.0
ports:
- "5173:5173"
develop:
watch:
- action: sync
path: ./frontend/src
target: /app/src
initial_sync: true
ignore:
- node_modules/
- dist/
- action: rebuild
path: ./frontend/package.json
backend:
build:
context: ./backend
command: npm run dev
ports:
- "3000:3000"
develop:
watch:
- action: sync
path: ./backend/src
target: /app/src
initial_sync: true
- action: rebuild
path: ./backend/package.json
이 구성에서 frontend/src와 backend/src는 저장 즉시 컨테이너에 반영됩니다. 프론트엔드는 Vite의 HMR이 화면 갱신을 맡고, 백엔드는 nodemon, tsx watch, spring-boot-devtools, uvicorn --reload 같은 프레임워크별 개발 서버가 재시작을 처리하는 구조가 일반적입니다.
중요한 포인트는 node_modules를 동기화하지 않는 것입니다. 호스트가 macOS 또는 Windows이고 컨테이너가 Linux인 경우, 네이티브 모듈이 OS나 CPU 아키텍처에 따라 달라질 수 있습니다. 또한 node_modules는 파일 수가 많아 감시와 동기화 비용이 커집니다. 따라서 의존성은 이미지 빌드 단계에서 설치하고, 소스만 Watch로 동기화하는 방식이 안정적입니다.
Python 프로젝트라면 app/ 또는 src/는 sync, requirements.txt는 rebuild로 두면 됩니다. Java나 Go처럼 컴파일 과정이 중요한 언어는 단순 동기화보다 rebuild 또는 컨테이너 내부 개발 도구의 watch 명령과 조합하는 편이 낫습니다.
Docker Compose Watch와 bind mount 비교
많은 개발자가 먼저 떠올리는 방식은 bind mount입니다. 예를 들어 ./src:/app/src처럼 호스트 폴더를 컨테이너에 직접 연결하면 파일 변경이 즉시 보입니다. 단순한 프로젝트에서는 여전히 좋은 선택입니다. 하지만 Docker Compose Watch는 더 세밀한 제어가 필요할 때 장점이 있습니다.
bind mount는 연결된 디렉터리를 그대로 노출합니다. 그래서 제외하고 싶은 파일이나 OS별로 달라지는 산출물이 섞이면 문제가 생길 수 있습니다. 반면 Watch는 ignore와 include로 감시 대상을 좁힐 수 있습니다. 예를 들어 src/는 동기화하되 dist/, .next/, node_modules/, coverage/는 제외하는 식입니다.
develop:
watch:
- action: sync
path: ./app
target: /app
ignore:
- node_modules/
- .next/
- dist/
- coverage/
다만 Watch가 bind mount를 완전히 대체한다고 보기는 어렵습니다. 로그 파일, 업로드 파일, 데이터베이스 초기화 스크립트처럼 호스트와 컨테이너가 같은 파일 시스템을 공유해야 편한 경우도 있습니다. 실무에서는 다음 기준으로 선택하면 됩니다.
- 소스 코드 자동 반영이 목적이면 Watch가 적합합니다.
- 양방향 파일 공유가 중요하면 bind mount가 단순합니다.
- 의존성 디렉터리 충돌이 걱정되면 Watch가 더 안전합니다.
- 빌드가 필요한 변경이 많으면
rebuild규칙을 명확히 분리해야 합니다.
Docker Compose Watch 문제 해결 체크리스트
Watch가 동작하지 않을 때는 대부분 경로, 권한, 액션 선택, 컨테이너 내부 개발 서버 설정 중 하나가 원인입니다. 먼저 path가 Compose 파일 기준 상대 경로인지 확인하세요. target은 컨테이너 내부 경로이며, sync 계열 액션에서 파일이 복사될 위치입니다. path와 target을 혼동하면 변경은 감지되지만 앱이 읽는 위치에는 반영되지 않을 수 있습니다.
권한도 자주 만나는 문제입니다. Docker 공식 문서에서는 Watch가 정상 동작하려면 이미지 안에 stat, mkdir, rmdir 같은 일반 명령이 있어야 하고, 컨테이너의 실행 사용자가 target 경로에 쓸 수 있어야 한다고 설명합니다. Dockerfile에서 비루트 사용자를 쓴다면 COPY --chown으로 소유권을 맞추는 것이 좋습니다.
FROM node:20
WORKDIR /app
RUN useradd -ms /bin/sh -u 1001 app
COPY package*.json ./
RUN npm install
COPY --chown=app:app . /app
USER app
CMD ["npm", "run", "dev"]
또 하나의 흔한 착각은 Watch만 켜면 애플리케이션이 자동 재시작한다고 생각하는 것입니다. sync는 파일을 컨테이너에 반영할 뿐, 프로세스를 반드시 재시작하지는 않습니다. 따라서 Node.js 백엔드는 nodemon이나 tsx watch, Python은 --reload, Spring은 DevTools처럼 컨테이너 내부에서 변경을 감지하는 개발 도구가 함께 필요할 수 있습니다. 재시작이 꼭 필요하다면 sync+restart를 선택하세요.
점검 순서는 다음과 같습니다.
docker compose version이 Watch 지원 버전인지 확인합니다.- 서비스에
build가 선언되어 있는지 확인합니다. path는 호스트 경로,target은 컨테이너 경로로 구분합니다.ignore패턴은 해당path기준 상대 경로로 작성합니다.- 컨테이너 사용자가
target에 쓸 수 있는지 확인합니다. sync만으로 부족하면sync+restart또는 개발 서버 watch 옵션을 사용합니다.
Docker Compose Watch 추천 설정 패턴
실무에서 가장 안정적인 패턴은 파일 종류별로 액션을 분리하는 것입니다. 모든 변경을 rebuild로 처리하면 정확하긴 하지만 느립니다. 모든 변경을 sync로 처리하면 빠르지만 의존성이나 런타임 상태가 꼬일 수 있습니다. 따라서 다음 기준을 추천합니다.
| 파일 유형 | 추천 action | 이유 |
|---|---|---|
src/, app/, pages/ |
sync |
코드만 빠르게 반영 |
package.json, lock 파일 |
rebuild |
의존성 설치 필요 |
Dockerfile |
rebuild |
이미지 레이어 변경 |
.env, 설정 파일 |
sync+restart |
프로세스 재시작 필요 가능성 |
| 빌드 산출물 | ignore |
불필요한 감시 비용 방지 |
최소 구성은 다음처럼 시작하면 됩니다.
develop:
watch:
- action: sync
path: ./src
target: /app/src
initial_sync: true
- action: rebuild
path: package.json
- action: rebuild
path: Dockerfile
이후 프로젝트가 커지면 ignore와 include를 추가합니다. include는 특정 패턴만 감시하고 싶을 때 유용합니다. 예를 들어 Go 프로젝트에서 .go 파일 변경만 rebuild 대상으로 삼고 싶다면 include: "*.go"처럼 작성할 수 있습니다. YAML에서 *는 특별한 의미가 있으므로 와일드카드 패턴은 따옴표로 감싸는 것이 안전합니다.
마지막으로 initial_sync: true는 기존 컨테이너가 있을 때 Watch 세션 시작 전에 파일 상태를 맞추는 데 도움이 됩니다. 컨테이너를 계속 재사용하는 개발 환경이라면 켜두는 편이 예측 가능성이 높습니다.
자주 묻는 질문
Docker Compose Watch는 운영 환경에서도 써도 되나요?
일반적으로 권장하지 않습니다. Docker Compose Watch는 개발 중 파일 변경을 빠르게 반영하기 위한 기능입니다. 운영 환경에서는 이미지 빌드, 태깅, 배포 파이프라인, 롤백 전략을 명확히 관리하는 편이 안전합니다.
docker compose up --watch와 docker compose watch의 차이는 무엇인가요?
docker compose up --watch는 서비스를 시작하면서 Watch 모드까지 함께 실행합니다. docker compose watch는 Watch 명령을 별도로 실행하는 방식이며, 필요에 따라 --no-up으로 서비스 시작 없이 감시만 수행할 수 있습니다. 로그를 분리해서 보고 싶다면 별도 명령이 더 편합니다.
Watch를 쓰면 bind mount를 제거해야 하나요?
항상 제거할 필요는 없습니다. 다만 같은 경로에 bind mount와 Watch를 동시에 적용하면 동작을 추적하기 어려워질 수 있습니다. 소스 코드 반영은 Watch, 데이터 공유는 volume 또는 bind mount처럼 목적을 나누는 것이 좋습니다.
파일을 저장했는데 화면이 갱신되지 않는 이유는 무엇인가요?
먼저 target 경로가 앱이 실제로 읽는 경로와 같은지 확인하세요. 그다음 컨테이너 내부 개발 서버가 Hot Reload 또는 자동 재시작을 지원하는지 확인해야 합니다. sync는 파일 복사만 수행하므로, 프로세스 재시작이 필요하면 sync+restart를 사용해야 합니다.
Docker Compose Watch에서 node_modules를 제외해야 하나요?
대부분의 Node.js 프로젝트에서는 제외하는 편이 좋습니다. 파일 수가 많아 성능 부담이 크고, 호스트 OS와 컨테이너 OS가 다를 때 네이티브 패키지 문제가 생길 수 있습니다. 의존성은 이미지 빌드 단계에서 설치하고 소스 코드만 동기화하는 구성이 안정적입니다.
핵심 요약
- Docker Compose Watch 사용법의 핵심은
develop.watch에 파일별 액션 규칙을 선언하는 것입니다. sync는 소스 코드처럼 빠른 반영이 필요한 파일에 적합합니다.rebuild는package.json,requirements.txt,Dockerfile처럼 이미지나 의존성이 바뀌는 파일에 적합합니다.sync+restart는 설정 파일처럼 복사 후 프로세스 재시작이 필요한 경우에 유용합니다.ignore로node_modules,dist,.next,coverage같은 디렉터리를 제외하면 성능과 안정성이 좋아집니다.- Watch가 동작하려면 컨테이너 사용자에게
target경로 쓰기 권한이 있어야 합니다. docker compose up --watch는 서비스 시작과 감시를 함께 처리하고,docker compose watch는 감시를 별도로 실행할 때 유용합니다.
결론적으로 Docker Compose Watch는 컨테이너 기반 개발 환경에서 저장 즉시 변경 사항을 반영하기 위한 실용적인 방법입니다. 처음에는 src는 sync, 의존성 파일은 rebuild, 설정 파일은 sync+restart라는 세 가지 규칙으로 시작해 보세요. 이후 프로젝트 구조에 맞춰 ignore, include, initial_sync를 조정하면 개발 속도와 환경 일관성을 함께 확보할 수 있습니다.
참고 자료: Docker 공식 문서의 Compose Watch 가이드(https://docs.docker.com/compose/how-tos/file-watch/), Compose Develop Specification(https://docs.docker.com/reference/compose-file/develop/), docker compose watch CLI Reference(https://docs.docker.com/reference/cli/docker/compose/watch/)를 기준으로 정리했습니다.

'DEV' 카테고리의 다른 글
| Google I/O 2026 Gemini 개발자 도구 총정리 (0) | 2026.05.24 |
|---|---|
| 그라파나 대시보드 완벽 가이드 2026 (0) | 2026.05.24 |
| MCP 서버 구축 방법 2026 입문 가이드 (0) | 2026.05.23 |
| AI 코딩 도구 비교 2026 완벽 가이드 (0) | 2026.05.23 |
| Next.js 15 App Router, 이것만 잡으면 된다 (0) | 2026.05.23 |
- Total
- Today
- Yesterday
- Java
- 프론트엔드개발
- n8n
- 배민
- ai 코딩 도구
- LLM
- 백엔드개발
- 미래ai
- SEO최적화
- 프롬프트엔지니어링
- 개발가이드
- 웹보안
- 로드밸런싱
- 개발자성장
- 개발생산성
- 클린코드
- 웹개발
- AI반도체
- AI
- 자바개발
- DevOps
- AI기술
- 생성형AI
- 마이크로서비스
- 클라우드컴퓨팅
- 데이터베이스
- springai
- 성능최적화
- 인공지능
- 개발자가이드
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | |||||
| 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 24 | 25 | 26 | 27 | 28 | 29 | 30 |
| 31 |
