Docker Compose Watch คืออะไร?
Docker Compose Watch เป็น feature ใหม่ของ Docker Compose (v2.22+) ที่ช่วยให้นักพัฒนาสามารถ monitor file changes และ sync หรือ rebuild containers โดยอัตโนมัติ ทำให้การพัฒนาแอปพลิเคชันใน containers มีประสิทธิภาพเทียบเท่าการพัฒนาแบบ local ทั่วไป
จุดเด่น
Docker Compose Watch ออกมาเพื่อแก้ปัญหา "Container Rebuild Hell" ที่ทำให้นักพัฒนาต้อง rebuild container ทุกครั้งที่แก้ไขโค้ด ทั้งๆ ที่หลายการเปลี่ยนแปลงไม่จำเป็นต้อง rebuild เลย
Feature นี้ได้รับการปล่อยออกมาเป็น General Available (GA) ในปี 2025 หลังจากอยู่ในช่วง beta มาระยะหนึ่ง ปัจจุบันสามารถใช้งานได้อย่างมั่นคงและเสถียร
ทำไมต้องใช้ Docker Compose Watch?
ปัญหาเดิม (ก่อนมี Watch)
- Rebuild ทุกครั้ง: แก้โค้ด 1 บรรทัด ต้อง rebuild container ทั้งก้อน
- รอนาน: Build time 3-5 นาทีต่อการแก้ไขเล็กน้อย
- Lost Flow: สูญเสีย concentration จากการรอ
- Manual Steps: ต้องพิมพ์คำสั่ง build/up ซ้ำๆ
ข้อดีของ Docker Compose Watch
- Instant Sync: ไฟล์ถูก sync เข้า container ทันที (milliseconds)
- Smart Rebuild: Rebuild เฉพาะเมื่อจำเป็น (dependencies)
- Stay Focused: ทำงานต่อเนื่อง ไม่มี interruption
- Zero Config: ใช้ config เดียวกับ production
| Feature | แบบเดิม | Docker Compose Watch |
|---|---|---|
| แก้โค้ด 1 บรรทัด | Rebuild 3-5 นาที | Sync ทันที (<1 วินาที) |
| แก้ package.json | Rebuild manual | Auto rebuild |
| Developer Flow | ขาดช่วงบ่อย | ต่อเนื่อง |
| Config Management | แยก dev/prod | ใช้ไฟล์เดียวกัน |
Actions ทั้ง 4 แบบ
Docker Compose Watch รองรับ 4 ประเภทของ actions ที่คุณสามารถกำหนดได้ตามความต้องการ:
sync
เร็วที่สุด - Hot Reloadคัดลอกไฟล์จาก host เข้าสู่ container ทันที โดยไม่ต้อง rebuild เหมาะสำหรับ source code ที่ไม่มี dependency changes
rebuild
สำหรับ Dependency ChangesRebuild container ใหม่ทั้งหมด เมื่อมีการเปลี่ยนแปลงไฟล์ที่ระบุ เช่น package.json, requirements.txt
sync+restart
Sync + Restart ContainerSync ไฟล์เข้า container และ restart container หลังจาก sync เสร็จ เหมาะสำหรับไฟล์ที่ต้อง restart process
sync+exec
Sync + Run CommandSync ไฟล์และรัน command ที่กำหนดหลังจาก sync เสร็จ เช่น run migrations, clear cache
การติดตั้งและใช้งาน
สิ่งที่ต้องเตรียม
- Docker Desktop 4.24+ หรือ Docker Engine 24.0+
-
Docker Compose v2.22+ (ตรวจสอบด้วย
docker compose version) - docker-compose.yml ที่มี service definitions
1 ตรวจสอบ Docker Compose Version
2
เพิ่ม develop section ใน docker-compose.yml
# docker-compose.yml
services:
frontend:
build: ./frontend
ports:
- "3000:3000"
develop:
watch:
# Sync source code (hot reload)
- action: sync
path: ./frontend/src
target: /app/src
# Rebuild เมื่อ package.json เปลี่ยน
- action: rebuild
path: ./frontend/package.json
backend:
build: ./backend
ports:
- "8000:8000"
develop:
watch:
# Sync Python files
- action: sync
path: ./backend/app
target: /app/app
# Rebuild เมื่อ requirements.txt เปลี่ยน
- action: rebuild
path: ./backend/requirements.txt
3 รัน Docker Compose Watch
4 ตรวจสอบการทำงาน
ตัวอย่างการใช้งานจริง
ตัวอย่างที่ 1: Node.js + React Frontend
# docker-compose.yml - React + Vite
services:
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
ports:
- "5173:5173"
environment:
- NODE_ENV=development
develop:
watch:
# Sync source code สำหรับ hot reload
- action: sync
path: ./frontend/src
target: /app/src
ignore:
- node_modules/
# Sync public assets
- action: sync
path: ./frontend/public
target: /app/public
# Sync config files (trigger HMR)
- action: sync
path: ./frontend/index.html
target: /app/index.html
# Rebuild เมื่อ dependencies เปลี่ยน
- action: rebuild
path: ./frontend/package.json
- action: rebuild
path: ./frontend/vite.config.js
ตัวอย่างที่ 2: Python + Django Backend
# docker-compose.yml - Django Backend
services:
backend:
build:
context: ./backend
dockerfile: Dockerfile
ports:
- "8000:8000"
environment:
- DEBUG=1
- DJANGO_SETTINGS_MODULE=myproject.settings.dev
volumes:
- sqlite_data:/app/db
develop:
watch:
# Sync Django app code
- action: sync+restart
path: ./backend/myproject
target: /app/myproject
# Sync และ run migrations อัตโนมัติ
- action: sync+exec
path: ./backend/myproject/migrations
target: /app/myproject/migrations
exec:
command: python manage.py migrate
# Rebuild เมื่อ requirements เปลี่ยน
- action: rebuild
path: ./backend/requirements.txt
# Sync env file (restart required)
- action: sync+restart
path: ./backend/.env
target: /app/.env
volumes:
sqlite_data:
sync+restart กับ Django เพราะต้อง restart process หลังจาก code changes (เว้นแต่ใช้ django-autoreload)
ตัวอย่างที่ 3: Go Backend with Air
# docker-compose.yml - Go Backend with Air
services:
api:
build:
context: ./api
dockerfile: Dockerfile.dev
ports:
- "8080:8080"
environment:
- GO_ENV=development
develop:
watch:
# Sync Go source code (Air จะ auto-reload)
- action: sync
path: ./api/cmd
target: /app/cmd
- action: sync
path: ./api/internal
target: /app/internal
- action: sync
path: ./api/pkg
target: /app/pkg
# Rebuild เมื่อ go.mod เปลี่ยน
- action: rebuild
path: ./api/go.mod
- action: rebuild
path: ./api/go.sum
FROM golang:1.21-alpine
WORKDIR /app
RUN go install github.com/cosmtrek/air@latest
COPY go.* ./
RUN go mod download
COPY . .
CMD ["air", "-c", ".air.toml"]
ตัวอย่างที่ 4: Full Stack (Frontend + Backend + Database)
# docker-compose.yml - Full Stack Application
services:
# Frontend - React + Vite
frontend:
build: ./frontend
ports:
- "5173:5173"
environment:
- VITE_API_URL=http://localhost:8000
develop:
watch:
- action: sync
path: ./frontend/src
target: /app/src
- action: rebuild
path: ./frontend/package.json
# Backend - Python FastAPI
backend:
build: ./backend
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/mydb
depends_on:
- db
develop:
watch:
- action: sync
path: ./backend/app
target: /app/app
- action: rebuild
path: ./backend/requirements.txt
# Database - PostgreSQL
db:
image: postgres:15-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: mydb
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
volumes:
postgres_data:
Best Practices
ใช้ .dockerignore
กำหนดไฟล์ที่ไม่ต้องการ sync เพื่อเพิ่มประสิทธิภาพ
ใช้ sync ก่อน rebuild
เลือก action ให้เหมาะสม - sync เร็วกว่า rebuild มาก
แยก dev และ prod config
ใช้ compose overrides สำหรับ development settings
ใช้ ignore patterns
กำหนดไฟล์ที่ไม่ต้องการ trigger watch
แก้ไขปัญหาที่พบบ่อย
ปัญหา: ไฟล์ไม่ถูก sync
สาเหตุ: Path ไม่ถูกต้องหรือมี permission issues
ปัญหา: Watch ไม่ทำงาน (ไม่ detect file changes)
สาเหตุ: ใช้ network filesystem หรือ inotify limit เกิน
ปัญหา: ใช้ memory สูงเกินไป
สาเหตุ: Watch มีไฟล์จำนวนมาก (node_modules, etc.)
ปัญหา: Rebuild ช้า
สาเหตุ: Docker layer caching ไม่ทำงาน
สรุป
สิ่งที่คุณได้เรียนรู้:
- Docker Compose Watch คืออะไร
- Actions ทั้ง 4 แบบ (sync, rebuild, sync+restart, sync+exec)
- การตั้งค่าและใช้งาน
- ตัวอย่างสำหรับ Node.js, Python, Go
- Best Practices และ Troubleshooting
ขั้นตอนต่อไป:
- ทดลองใช้กับโปรเจคที่มีอยู่
- ปรับแต่ง watch config ให้เหมาะกับ workflow
- ศึกษา Docker BuildKit สำหรับ build optimization