Docker_257_Inno
Link
1. Mở đầu: Vấn đề "Kinh điển" (3 phút)
-
Slide 1: Tiêu đề - Tên buổi TechTalk, tên người nói, logo team AI.
-
Slide 2: Nỗi đau "Trên máy em chạy ngon mà!"
-
Bắt đầu bằng một câu chuyện hài hước hoặc một meme về câu nói "It works on my machine".
-
Liệt kê các vấn đề thực tế mà team dev và AI thường gặp:
-
Developer A: Dùng Windows, Python 3.9, TensorFlow 2.10.
-
Developer B: Dùng MacOS, Python 3.10, TensorFlow 2.11.
-
Server Staging: Dùng Ubuntu, Python 3.8, thư viện X, Y, Z...
-
Kết quả: Code của người A không chạy được trên máy người B, và khi deploy lên server thì lỗi tùm lum về phiên bản thư viện, môi trường hệ điều hành.
-
-
Nhấn mạnh: Vấn đề này làm lãng phí thời gian, gây khó khăn trong hợp tác và triển khai sản phẩm.
-
2. Giải pháp diệu kỳ: Docker là gì? (7 phút)
-
Slide 3: Giới thiệu Docker - Phép ẩn dụ về Công-ten-nơ 📦
-
"Hãy tưởng tượng bạn cần vận chuyển một món đồ quý giá (là code của bạn). Thay vì gói ghém sơ sài, bạn cho nó vào một chiếc công-ten-nơ tiêu chuẩn, niêm phong lại. Chiếc công-ten-nơ này có thể được chở bằng bất kỳ tàu hỏa, tàu thủy, xe tải nào mà không cần quan tâm bên trong là gì."
-
Docker chính là cái công-ten-nơ đó. Nó đóng gói mã nguồn của bạn CÙNG VỚI tất cả các thứ phụ thuộc (thư viện, runtime, biến môi trường, file cấu hình) vào một đơn vị duy nhất gọi là Image.
-
- Slide 4: Các khái niệm cốt lõi (Giải thích đơn giản)
-
Dockerfile: Là một file văn bản chứa chỉ dẫn để xây dựng Image (giống như bản thiết kế chi tiết của công-ten-nơ).
-
Image: Là khuôn mẫu đóng gói, chỉ đọc (read-only). Nó chứa ứng dụng và mọi thứ cần thiết để chạy.
-
Container: Là một thực thể (instance) đang chạy của Image. Bạn có thể tạo, bắt đầu, dừng, xóa container. Đây chính là ứng dụng của bạn đang "sống".
-
Docker Hub/Registry: Là kho lưu trữ các Image (giống như GitHub cho code).
Lợi ích chính (5 phút)
-
Slide 5: Tại sao Docker lại thay đổi cuộc chơi?
-
Nhất quán (Consistency): Chạy ở đâu cũng như nhau. Tạm biệt "works on my machine".
-
Di động (Portability): Dễ dàng di chuyển ứng dụng giữa các môi trường (local, staging, production).
-
Cô lập (Isolation): Các container chạy độc lập, không ảnh hưởng lẫn nhau, giúp quản lý dependency dễ dàng hơn nhiều.
-
Hiệu quả (Efficiency): Khởi động nhanh và tốn ít tài nguyên hơn so với máy ảo (Virtual Machine).
-
Slide 5: Tối ưu quá trình Build ⚡️ (4 phút)
- Hiển thị một
Dockerfileđơn giản.
- Layer Caching (Bộ đệm lớp):
-
Chỉ vào các dòng lệnh trong Dockerfile (
COPY,RUN). -
Giải thích: "Mỗi dòng lệnh này tạo ra một 'lớp' (layer). Docker rất thông minh, nếu file
requirements.txtkhông thay đổi, nó sẽ dùng lại lớp đã cài đặt thư viện từ lần build trước, giúp tiết kiệm thời gian cực lớn. Đây gọi là Layer Caching." -
Mẹo: Đó là lý do chúng ta nên
COPY requirements.txtvàRUN pip installtrước khiCOPYtoàn bộ source code.
docker compose up --build -d
docker compose down -v
docker system prune -a
- Multi-stage Builds (Build đa giai đoạn) 🏗️:
-
Hiển thị một
Dockerfilecó 2 stage:AS buildervà stage cuối cùng. -
Giải thích: "Với các ứng dụng cần biên dịch, stage 1 (builder) sẽ cài tất cả công cụ cần thiết để build. Stage 2 (final) chỉ lấy duy nhất file kết quả từ stage 1. Kết quả là Image cuối cùng siêu nhỏ và an toàn hơn vì không chứa các công cụ không cần thiết."
cách cấu trúc dự án Docker theo kiểu tách biệt và các kiểu cấu trúc khác.
Chắc chắn rồi, đây là cách cấu trúc dự án Docker theo kiểu tách biệt và các kiểu cấu trúc khác.
Cách bạn mô tả — tách mỗi dịch vụ ra một thư mục riêng với Dockerfile của nó, và dùng một file docker-compose.yml ở thư mục gốc để điều phối — là cách làm phổ biến, hiệu quả và được khuyên dùng nhất cho hầu hết các dự án.
## Kiểu 1: Cấu trúc Microservices với Docker Compose (Phổ biến nhất)
Đây chính là cấu trúc bạn đã đề cập. Nó cực kỳ phù hợp cho các dự án có nhiều thành phần (ví dụ: frontend, backend, database).
Cấu trúc thư mục:
my-project/
├── docker-compose.yml
├── backend/
│ ├── Dockerfile
│ ├── main.py
│ └── requirements.txt
├── frontend/
│ ├── Dockerfile
│ ├── src/
│ └── package.json
└── nginx/
└── nginx.conf
Cách hoạt động:
File docker-compose.yml ở thư mục gốc sẽ định nghĩa các services và chỉ định nơi để "build" image cho từng service đó.
docker-compose.yml ví dụ:
version: '3.8'
services:
backend:
build:
context: ./backend # Trỏ đến thư mục chứa Dockerfile của backend
dockerfile: Dockerfile
ports:
- "8000:8000"
volumes:
- ./backend:/app
frontend:
build:
context: ./frontend # Trỏ đến thư mục chứa Dockerfile của frontend
ports:
- "3000:3000"
# ... các services khác như database, redis ...
-
Ưu điểm:
- Rõ ràng, dễ quản lý: Mỗi service hoàn toàn độc lập, có
Dockerfilevà source code riêng. - Dễ bảo trì và mở rộng: Nâng cấp hay thay đổi một service không ảnh hưởng đến các service khác.
- Tái sử dụng: Dễ dàng tái sử dụng từng service cho các dự án khác.
- Tận dụng build cache hiệu quả: Build lại một service chỉ ảnh hưởng đến chính nó.
- Rõ ràng, dễ quản lý: Mỗi service hoàn toàn độc lập, có
-
Nhược điểm:
- Số lượng file và thư mục nhiều hơn một chút so với các cách khác.
## Các kiểu cấu trúc khác
Ngoài cách trên, còn có một vài kiểu cấu trúc khác, mỗi kiểu phù hợp với các trường hợp sử dụng khác nhau.
## Kiểu 2: Monolithic Dockerfile (Dùng Multi-stage builds)
Kiểu này gộp tất cả các bước build của nhiều thành phần vào một Dockerfile duy nhất đặt ở thư mục gốc, sử dụng kỹ thuật multi-stage builds.
Cấu trúc thư mục:
my-project/
├── Dockerfile # Dockerfile duy nhất
├── docker-compose.yml
├── backend/
│ ├── main.py
│ └── requirements.txt
└── frontend/
├── src/
└── package.json
Cách hoạt động:
Dockerfile sẽ có nhiều giai đoạn (stage), ví dụ: một stage để build frontend, một stage để cài đặt backend, và stage cuối cùng để tổng hợp kết quả.
Dockerfile (Multi-stage) ví dụ:
# Stage 1: Build frontend
FROM node:18 AS frontend-builder
WORKDIR /app
COPY frontend/package.json .
RUN npm install
COPY frontend/ .
RUN npm run build
# Stage 2: Build backend
FROM python:3.9-slim AS final-image
WORKDIR /app
COPY --from=frontend-builder /app/build /app/static # Copy kết quả build frontend
COPY backend/requirements.txt .
RUN pip install -r requirements.txt
COPY backend/ .
CMD ["python", "main.py"]
docker-compose.yml lúc này sẽ rất đơn giản:
services:
app:
build: . # Build từ Dockerfile ở thư mục hiện tại
ports:
- "8000:8000"
-
Ưu điểm:
- Gọn gàng, ít file
Dockerfilehơn. - Phù hợp cho các ứng dụng đơn giản, liên kết chặt chẽ (ví dụ: backend Python phục vụ luôn cả file static của frontend).
- Gọn gàng, ít file
-
Nhược điểm:
Dockerfiletrở nên rất phức tạp và khó bảo trì khi dự án lớn lên.- Mỗi khi build lại, có thể phải chạy lại tất cả các stage, làm mất thời gian.
- Khó tách biệt và tái sử dụng các thành phần.
## Kiểu 3: Sử dụng Image Registry (Cho Production & CI/CD)
Đây là một biến thể nâng cao của kiểu 1, thường được dùng trong môi trường chuyên nghiệp với CI/CD (Tích hợp/Triển khai liên tục).
Cách hoạt động:
- Mỗi service (frontend, backend) vẫn có
Dockerfileriêng trong thư mục của nó. - Thay vì
docker-composetự build, một hệ thống CI/CD (như GitLab CI, GitHub Actions) sẽ tự động build image cho mỗi service khi có code mới được đẩy lên. - Các image sau khi build xong sẽ được đẩy lên một kho lưu trữ image (Image Registry) như Docker Hub, GitLab Container Registry, hoặc AWS ECR.
- File
docker-compose.ymlsẽ không dùngbuildnữa, mà dùngimageđể kéo các image đã được build sẵn từ registry về.
docker-compose.yml ví dụ:
version: '3.8'
services:
backend:
image: my-registry/my-project/backend:1.2.0 # Kéo image từ registry
ports:
- "8000:8000"
frontend:
image: my-registry/my-project/frontend:2.5.1 # Kéo image đã được build sẵn
ports:
- "3000:3000"
-
Ưu điểm:
- Tốc độ triển khai cực nhanh: Không cần phải build lại mỗi lần chạy, chỉ cần kéo image.
- Quản lý phiên bản chuyên nghiệp: Dễ dàng triển khai một phiên bản cụ thể của service (ví dụ:
backend:1.2.0). - Tách biệt hoàn toàn giữa build và run: Team phát triển không cần cài Docker trên máy production, chỉ cần kéo và chạy.
- Phù hợp tuyệt đối với CI/CD và môi trường production.
-
Nhược điểm:
- Cần thiết lập hệ thống CI/CD và registry, phức tạp hơn cho các dự án nhỏ.
| Tiêu chí | Kiểu 1: Microservices (Khuyên dùng) | Kiểu 2: Monolithic Dockerfile | Kiểu 3: Image Registry (Production) |
|---|---|---|---|
| Độ phức tạp | Trung bình | Thấp (ban đầu), Cao (khi lớn) | Cao (thiết lập ban đầu) |
| Bảo trì | Tốt | Kém | Rất tốt |
| Khả năng mở rộng | Rất tốt | Kém | Rất tốt |
| Tốc độ triển khai | Trung bình (cần build) | Chậm (build phức tạp) | Nhanh (chỉ kéo image) |
| Phù hợp nhất cho | Hầu hết các dự án | Dự án nhỏ, đơn giản | Môi trường Production, CI/CD |
Lỗi mình mắc phải
- Nếu trong cùng network thì nó giao tiếp với nhau qua tên service - chứ không phải localhost. \
QUestion
docker engine ---