depends_on คืออะไร?
depends_on เป็น option ใน Docker Compose ที่ใช้กำหนดความสัมพันธ์ระหว่าง Service ว่า Service ไหนต้องเริ่มก่อน Service ไหน เช่น Application Server ต้องรอให้ Database พร้อมก่อนจึงจะเริ่มทำงานได้
ปัญหาที่พบบ่อยคือ เมื่อรัน docker compose up พร้อมกันทุก Container ตัว App อาจพยายามเชื่อมต่อ Database ก่อนที่ Database จะพร้อมรับการเชื่อมต่อ ทำให้เกิด Error และ App ล้มเหลว
รูปแบบพื้นฐานของ depends_on
version: '3.8'
services:
app:
image: myapp:latest
depends_on:
- db
- redis
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: secret
redis:
image: redis:7-alpine
ในตัวอย่างนี้ service app จะไม่เริ่มต้นจนกว่า db และ redis จะถูก start ขึ้นมาก่อน
ข้อจำกัดของ depends_on แบบพื้นฐาน
depends_on แบบธรรมดาจะรอแค่ให้ Container เริ่มต้น (started) เท่านั้น ไม่ได้รอให้ Service พร้อมใช้งาน (healthy/ready) จริงๆ
เช่น MySQL Container อาจเริ่ม Process แล้ว แต่ยังไม่พร้อมรับ Connection ในช่วงแรก ทำให้ App ยังเชื่อมต่อไม่ได้
ใช้ condition เพื่อรอให้ Service พร้อม
Docker Compose รองรับ condition 3 แบบ:
service_started— รอแค่ให้ Container เริ่มต้น (ค่า default)service_healthy— รอให้ Healthcheck ผ่านservice_completed_successfully— รอให้ Service ทำงานเสร็จและออกด้วย exit code 0
ตัวอย่าง: รอ MySQL จนกว่าจะ Healthy
version: '3.8'
services:
app:
image: myapp:latest
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: mydb
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
redis:
image: redis:7-alpine
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 3
อธิบาย Healthcheck แต่ละ Option
| Option | ความหมาย | ค่าแนะนำ |
|---|---|---|
| test | คำสั่งที่ใช้ทดสอบ | ขึ้นอยู่กับ Service |
| interval | ระยะเวลาระหว่างการทดสอบ | 10s-30s |
| timeout | เวลาสูงสุดที่รอผล | 3s-10s |
| retries | จำนวนครั้งที่ลองซ้ำก่อนถือว่า unhealthy | 3-5 |
| start_period | เวลาให้ Service เริ่มต้นก่อนนับ retries | 10s-60s |
ตัวอย่าง: Web App + PostgreSQL + Redis
version: '3.8'
services:
web:
build: .
ports:
- "8000:8000"
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
environment:
DATABASE_URL: postgresql://user:password@postgres:5432/mydb
REDIS_URL: redis://redis:6379
postgres:
image: postgres:15-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: mydb
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d mydb"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 3
volumes:
postgres_data:
depends_on กับ restart policy
แนะนำใช้ร่วมกับ restart: on-failure หรือ restart: unless-stopped เพื่อให้ App ลอง restart ถ้าเชื่อมต่อ Database ไม่ได้ในครั้งแรก
app:
image: myapp:latest
restart: on-failure
depends_on:
db:
condition: service_healthy
service_completed_successfully ใช้เมื่อไหร่?
เหมาะสำหรับ Migration หรืองาน Init ที่ต้องทำก่อน Application จะเริ่ม:
services:
migrate:
image: myapp:latest
command: python manage.py migrate
depends_on:
db:
condition: service_healthy
app:
image: myapp:latest
depends_on:
migrate:
condition: service_completed_successfully
db:
condition: service_healthy
สรุป
การใช้ depends_on ร่วมกับ condition: service_healthy และ healthcheck เป็นวิธีที่ถูกต้องที่สุดในการจัดการลำดับการเริ่มต้น Container ใน Docker Compose ช่วยให้แน่ใจว่า Service ทุกตัวพร้อมใช้งานจริงก่อน Application จะเริ่มทำงาน

