Giao diện
Module 3: Orchestration with Docker Compose (Hợp tấu Container)
🎓 Instructor Profile
Kỹ sư Raizo (Phó CTO HPN) - Chuyên gia kiến trúc hệ thống, người tin rằng "Một container lẻ loi là một container buồn". Cùng Giáo sư Tom giải mã sự kỳ diệu của việc phối hợp dịch vụ.
Chào mừng các bạn đến với thế giới của Orchestration. Nếu Dockerfile là cách bạn tạo ra một "ngôi sao" (Container), thì Docker Compose chính là người nhạc trưởng (Conductor) điều khiển cả dàn nhạc giao hưởng.
🎻 Phần 1: From Solo to Symphony (Từ Đơn lẻ đến Hợp xướng)
Nỗi đau của Developer (The Pain Point)
Hãy tưởng tượng bạn đang phát triển một Web App hiện đại. Bạn cần bật:
- Frontend (React/Vue)
- Backend (Node/Go/Python)
- Database (PostgreSQL)
- Cache (Redis)
- Worker (Xử lý tác vụ nền)
Bạn phải mở 5 tab Terminal, gõ 5 lệnh docker run dài ngoằng nhớ nhớ quên quên. Sai một tham số là hệ thống "gãy".
Giải pháp: Infrastructure as Code (IaC)
docker-compose.yml ra đời. Nó là bản tuyên ngôn của hệ thống (Manifest). Chỉ với một file duy nhất và một lệnh duy nhất, cả thế giới của bạn sẽ được dựng lên.
"Define and run multi-container Docker applications."
📐 Phần 2: The YAML Blueprint (Bản vẽ kỹ thuật)
Docker Compose sử dụng định dạng YAML (YAML Ain't Markup Language). Cấu trúc của nó rất trong sáng, dễ đọc.
💡 Compose V2 vs V1
Hiện tại, Docker đã chuyển sang Compose V2 (được viết lại bằng Go, tích hợp thẳng vào Docker CLI).
- V1 (Cũ):
docker-compose up(có gạch nối). - V2 (Mới):
docker compose up(dùng dấu cách). PENALGO dạy chuẩn V2.
Cấu trúc giải phẫu
yaml
# Phiên bản schema (thường dùng 3.8 hoặc mới nhất)
version: "3.8"
services:
# --- Dịch vụ 1: Web App ---
web:
build: . # Build từ Dockerfile ở thư mục hiện tại
ports:
- "8000:5000" # Mapping port Host:Container
depends_on:
- db # Chỉ chạy sau khi 'db' khởi động
# --- Dịch vụ 2: Database ---
db:
image: postgres:15-alpine
volumes:
- db_data:/var/lib/postgresql/data # 📦 Persist data
environment:
POSTGRES_PASSWORD: ${DB_PASS} # 🛡️ Dùng biến môi trường
volumes:
db_data: # Khai báo volume dùng chung
networks:
app_network: # 🔗 Kết nối mạng (Tuỳ chọn, Docker tự tạo default network)🌐 Phần 3: Networking & Service Discovery (Ma thuật kết nối)
Tư duy Architect: Làm thế nào Frontend tìm thấy Backend, hay Backend tìm thấy Database khi IP của container thay đổi liên tục mỗi khi khởi động lại?
Docker Compose giải quyết bằng Internal DNS. Trong cùng một mạng Compose (default network), các dịch vụ gọi nhau bằng Service Name.
- Để kết nối tới Database Postgres, Backend chỉ cần dùng host:
db(Tên service khai báo trong YAML). - Connection String:
postgres://user:pass@db:5432/dbname(Tuyệt đối không dùng IP như172.18.0.2).
🔐 Phần 4: Environment & Secrets (Quản lý bí mật)
☠️ SECURITY ALERT
Tuyệt đối KHÔNG BAO GIỜ hardcode mật khẩu, API Key trực tiếp trong file docker-compose.yml và commit lên Git. Đây là lỗi sơ đẳng nhất khiến server bị hack.
Best Practice: Sử dụng .env
Docker Compose tự động đọc file .env đặt cùng thư mục.
Tạo file
.env:iniDB_USER=admin DB_PASS=SieuMatKhau123!@#Sử dụng trong YAML:
yamlenvironment: - POSTGRES_USER=${DB_USER} - POSTGRES_PASSWORD=${DB_PASS}Thêm vào
.gitignore:text.env
🚦 Phần 5: The Startup Order Problem (Vấn đề thứ tự khởi động)
Đây là kiến thức Deep Tech quan trọng.
Vấn đề: Bạn dùng depends_on: - db cho Web App. Docker đảm bảo container db được BẬT lên trước web. Nhưng: Docker không biết khi nào Database bên trong sẵn sàng nhận kết nối (Ready). Postgres có thể mất 10s để khởi động tiến trình. Web App chạy lên ngay -> Kết nối DB -> Lỗi "Connection Refused" -> Crash. 💥
Giải pháp: Healthchecks (Khám sức khỏe)
Sử dụng healthcheck kết hợp condition: service_healthy.
yaml
services:
# Database có cơ chế tự khám bệnh
db:
image: postgres:15-alpine
healthcheck:
test: ["CMD-SHELL", "pg_isready -U admin"] # Lệnh kiểm tra
interval: 5s
timeout: 5s
retries: 5
# Web App kiên nhẫn đợi bác sĩ bảo "Khỏe" mới chạy
web:
build: .
depends_on:
db:
condition: service_healthy # 🟢 CHÌA KHÓA CỦA VẤN ĐỀ🛠️ Phần 6: Essential Commands (Bộ công cụ chỉ huy)
| Lệnh | Tác dụng | Chú thích |
|---|---|---|
docker compose up -d | Dựng toàn bộ stack và chạy ngầm (Detached). | Lệnh dùng nhiều nhất. |
docker compose down | Tắt và xóa containers, networks. | Giữ lại Volumes (Dữ liệu an toàn). |
docker compose down -v | Tắt và XÓA SẠCH cả Volumes. | ⚠️ Cẩn thận: Mất dữ liệu vĩnh viễn. Chỉ dùng khi muốn reset sạch sẽ. |
docker compose logs -f [service] | Xem log thời gian thực của dịch vụ cụ thể. | VD: docker compose logs -f web |
docker compose exec [service] [cmd] | Chui vào container đang chạy để debug. | VD: docker compose exec db psql -U admin |
🏆 Challenge: The Resilient Stack
Nhiệm vụ: Viết file docker-compose.yml dựng hệ thống sau:
- Redis Service:
- Image:
redis:alpine - Có mật khẩu (Lấy từ biến môi trường
${REDIS_PASS}). - Có Healthcheck (Dùng lệnh
redis-cli ping).
- Image:
- Web Service:
- Image:
nginx:alpine - Port:
8080:80 - Yêu cầu: Chỉ được phép khởi động SAU KHI Redis báo trạng thái "Healthy".
- Image:
Gợi ý lệnh test sức khỏe Redis: redis-cli -a $REDIS_PASSWORD ping | grep PONG
Chúc các bạn thành công trong việc điều phối dàn nhạc container của mình! 🎼