Giao diện
Thực hành: Docker Compose Orchestration
🎯 Mục tiêu
🎯 Sau bài thực hành này, bạn sẽ:
- Thiết kế
docker-compose.ymlcho ứng dụng multi-service - Cấu hình networks, volumes, và environment variables đúng cách
- Phân biệt
depends_onvà healthcheck để quản lý startup order - Chọn networking strategy phù hợp cho microservices
Phần 1: Trắc nghiệm
🧠 Quiz
Câu 1: depends_on trong Docker Compose đảm bảo điều gì?
- [ ] A) Service phụ thuộc chỉ start khi service kia healthy và sẵn sàng nhận request
- [x] B) Service phụ thuộc chỉ start sau khi container của service kia đã được tạo
- [ ] C) Tự động restart service nếu dependency bị crash
- [ ] D) Chia sẻ network giữa hai service
💡 Giải thích:
depends_onchỉ đảm bảo thứ tự khởi tạo container — KHÔNG đợi service thực sự ready. Dùnghealthcheckvớicondition: service_healthyđể đợi service sẵn sàng.
🧠 Quiz
Câu 2: Sự khác biệt giữa named volume và bind mount trong Compose?
- [ ] A) Không có khác biệt — cả hai đều mount thư mục host vào container
- [ ] B) Named volume nhanh hơn bind mount trên mọi hệ điều hành
- [x] C) Named volume do Docker quản lý và persist data, bind mount map trực tiếp thư mục host
- [ ] D) Bind mount chỉ hoạt động trên Linux, named volume hoạt động mọi nơi
💡 Giải thích: Named volume (
db-data:/var/lib/postgresql/data) được Docker quản lý, persist độc lập với container. Bind mount (./src:/app/src) map trực tiếp thư mục host — phù hợp dev nhưng không nên cho production data.
🧠 Quiz
Câu 3: Khi hai service cùng Compose file, chúng giao tiếp với nhau qua gì?
- [ ] A) Địa chỉ IP cố định được gán cho mỗi container
- [ ] B) Localhost với port mapping
- [x] C) Service name làm hostname trên default network của Compose
- [ ] D) Phải cấu hình DNS server riêng
💡 Giải thích: Docker Compose tự tạo default network. Service
apigọihttp://db:5432được vì Compose đăng ký DNS với service name. Không cần expose port ra host để giao tiếp nội bộ.
Phần 2: Sắp xếp Compose File
🧩 Parsons Problem
Bài 1: Compose cho Web App + Database
Sắp xếp các phần của docker-compose.yml đúng thứ tự logic:
- Khai báo
services:ở top level - Định nghĩa service
dbvới imagepostgres:16-alpine - Cấu hình environment variables cho database (user, password, db name)
- Mount named volume
db-datavào/var/lib/postgresql/data - Thêm healthcheck:
pg_isready -U postgres - Định nghĩa service
apivớibuild: ./api - Set
depends_on: dbvớicondition: service_healthy - Map port
3000:3000cho serviceapi - Khai báo
volumes:ở top level vớidb-data:
🧩 Parsons Problem
Bài 2: Networking cho 3 Service
Sắp xếp cấu hình networking:
- Khai báo
networks:vớifrontendvàbackend - Service
nginxkết nối cảfrontendvàbackend, map port80:80 - Service
apichỉ kết nốibackend - Service
dbchỉ kết nốibackend, không expose port ra host
Phần 3: Kịch bản thực tế
🎯 Scenario Choice
Chọn Networking Strategy cho Microservices
Tình huống: Hệ thống e-commerce gồm: frontend (React/Nginx), api-gateway, user-service, order-service, postgres.
Yêu cầu: Database không được truy cập từ frontend. Chỉ api-gateway expose port ra ngoài.
Câu hỏi: Bạn sẽ tổ chức network như thế nào?
Xem giải pháp gợi ý
Tạo 2 custom networks:
public-net—frontend+api-gatewayprivate-net—api-gateway+user-service+order-service+postgres
Lý do:
api-gatewayở cả 2 network — bridge giữa frontend và backendpostgreschỉ ởprivate-net— frontend không thể truy cập trực tiếp- Chỉ expose port
80trênapi-gateway
yaml
networks:
public-net:
private-net:
services:
frontend:
networks: [public-net]
api-gateway:
networks: [public-net, private-net]
ports: ["80:80"]
user-service:
networks: [private-net]
order-service:
networks: [private-net]
postgres:
networks: [private-net]WARNING
Compose phù hợp cho development và single-host. Multi-host cần Kubernetes hoặc Docker Swarm.