01The Inner Loop Problem
02How Compose Watch Works
1services: 2 web: 3 build: .4 ports: 5 - "3000:3000"6 develop: 7 watch: 8 # Sync source files — hot reload via nodemon/vite9 - action: sync10 path: ./src11 target: /app/src1213 # Rebuild when dependencies change14 - action: rebuild15 path: ./package.json1617 # Rebuild when Dockerfile changes18 - action: rebuild19 path: ./Dockerfile2021 # Sync+restart for config files22 - action: sync+restart23 path: ./config24 target: /app/config03Configuration by Language
1# Python (Django/Flask) — sync source, rebuild on deps2services: 3 api: 4 build: ./backend5 develop: 6 watch: 7 - action: sync8 path: ./backend/app9 target: /app/app10 - action: rebuild11 path: ./backend/requirements.txt12 - action: sync+restart13 path: ./backend/gunicorn.conf.py14 target: /app/gunicorn.conf.py1516# Go — rebuild on any .go change (compiled language)17 worker: 18 build: ./worker19 develop: 20 watch: 21 - action: rebuild22 path: ./worker/23 # Ignore non-Go files to avoid unnecessary rebuilds24 ignore: 25 - "**/*.md"26 - "**/*_test.go"2728# PHP (Laravel) — sync everything, restart on config29 php: 30 build: ./php31 develop: 32 watch: 33 - action: sync34 path: ./php/app35 target: /var/www/html/app36 - action: sync37 path: ./php/resources38 target: /var/www/html/resources39 - action: sync+restart40 path: ./php/.env41 target: /var/www/html/.envFor interpreted languages (Python, Node.js, PHP, Ruby), use sync for source files and let the framework's built-in reload handle the rest. For compiled languages (Go, Rust, Java), use rebuild — there's no shortcut around recompilation. Use multi-stage Docker builds to keep rebuild times short.
04Ignore Patterns and Performance
1services: 2 web: 3 build: .4 develop: 5 watch: 6 - action: sync7 path: ./src8 target: /app/src9 ignore: 10 - "node_modules/"11 - "**/*.test.ts"12 - "**/*.spec.ts"13 - "**/__tests__/"14 - "**/.DS_Store"15 - "**/*.swp"16 - "**/coverage/"17 - "**/.git/"1819 - action: rebuild20 path: ./package.json2122 - action: rebuild23 path: ./package-lock.jsonIn monorepos or projects with many files (10,000+), Compose Watch can cause high CPU usage from filesystem event processing. If you notice your machine slowing down, narrow the watch paths to specific directories rather than watching the entire project root. Watch ./src instead of ./ and add aggressive ignore patterns.
05Watch vs Bind Mounts
06A Complete Development Workflow
1services: 2 frontend: 3 build: 4 context: ./frontend5 target: development6 ports: 7 - "3000:3000"8 environment: 9 - API_URL=http://api:800010 develop: 11 watch: 12 - action: sync13 path: ./frontend/src14 target: /app/src15 - action: rebuild16 path: ./frontend/package.json1718 api: 19 build: 20 context: ./backend21 target: development22 ports: 23 - "8000:8000"24 environment: 25 - DATABASE_URL=postgresql://app:secret@db:5432/myapp26 depends_on: 27 db: 28 condition: service_healthy29 develop: 30 watch: 31 - action: sync32 path: ./backend/app33 target: /app/app34 - action: rebuild35 path: ./backend/requirements.txt36 - action: sync+restart37 path: ./backend/alembic38 target: /app/alembic3940 db: 41 image: postgres:16-alpine42 environment: 43 - POSTGRES_DB=myapp44 - POSTGRES_USER=app45 - POSTGRES_PASSWORD=secret46 volumes: 47 - pgdata:/var/lib/postgresql/data48 healthcheck: 49 test: ["CMD", "pg_isready", "-U", "app"]50 interval: 5s51 timeout: 3s52 retries: 55354volumes: 55 pgdata: