Docker Images – Vì sao Image nhỏ, nhanh và phù hợp với CI/CD?
Ở bài trước, chúng ta đã học:
Bài này đi sâu vào cấu trúc Docker Image và cơ chế Layers giúp Docker Build, Pull và Deploy hiệu quả.
1. Docker Image là gì?
Docker Image là một đối tượng immutable, đóng gói Application cùng Dependencies và các chỉ dẫn cần thiết để chạy ứng dụng.
Khác với VM:
Virtual Machine
├── Application
├── Libraries
├── Guest OS
└── Kernel
Docker Image
├── Application
├── Libraries
└── Dependencies
│
▼
Host Kernel
Image không chứa đầy đủ kernel và drivers như VM. Container sử dụng kernel do Host cung cấp.
Vì không phải boot một Guest OS hoàn chỉnh, Container thường khởi động nhanh hơn VM.
2. Vì sao Docker Image nhỏ?
Một Image dựa trên Ubuntu không có nghĩa chứa toàn bộ software như Ubuntu VM.
Minimal Image thậm chí có thể thiếu:
bash
curl
ping
vim
Image chỉ nên chứa những binaries và dependencies mà Application thực sự cần.
Điều này giúp Image nhỏ hơn, phân phối nhanh hơn và giảm các thành phần không cần thiết.
3. Đừng sửa Container – hãy Build Image mới
Giả sử Production chạy:
example-app:1.0
Khi cần thay đổi code hoặc cài thêm dependency, không nên đăng nhập vào Container và sửa trực tiếp.
Cách phù hợp hơn:
Source Code
↓
Modify
↓
docker build
↓
example-app:1.1
↓
Test
↓
Deploy
Như vậy Staging và Production có thể sử dụng cùng một phiên bản Image, giúp duy trì Dev/Prod Parity và hỗ trợ tự động hóa CI/CD.
4. Container nên có tính Ephemeral
Container nên có khả năng:
mà không làm mất state quan trọng.
Đây chính là tư tưởng Stateless Processes trong 12-Factor App.
Container
│
└── Application
Persistent State
│
└── External Storage / Database
Dữ liệu quan trọng không nên phụ thuộc vào vòng đời Container. 5. Docker Image được xây dựng từ Layers
Docker Image không phải một khối filesystem duy nhất mà được cấu thành từ nhiều Layers.
Ví dụ:
┌─────────────────────┐
│ Application Code │
├─────────────────────┤
│ Python Dependencies │
├─────────────────────┤
│ Python Runtime │
├─────────────────────┤
│ Ubuntu │
└─────────────────────┘
Một Image có thể sử dụng Image khác làm nền tảng:
Ubuntu 18.04
↓
Python 3.8
↓
example-app:1.0
Ở đây python:3.8 là Parent Image của example-app:1.0.
Image cũng có thể bắt đầu từ:
FROM scratch
scratch đại diện cho điểm bắt đầu trống. 6. Layer Cache – lý do Docker Build nhanh
Các Layer có thể được lưu trong cache và tái sử dụng.
Ubuntu
│
Python
/ \
/ \
App 1.0 App 2.0
Nếu Ubuntu và Python Layers đã tồn tại, Docker không cần tải hoặc lưu lại chúng cho mỗi Image mới.
Điều này giúp:
Build nhanh hơn → Push/Pull hiệu quả hơn → tiết kiệm Storage → CI/CD nhanh hơn.
Nếu chỉ Application Code thay đổi, các Layer trước đó vẫn có thể được tái sử dụng. Nhưng khi một Layer sớm trong quá trình Build thay đổi, các bước phụ thuộc phía sau có thể phải Build lại.
Vì vậy, thứ tự các instruction trong Dockerfile ảnh hưởng trực tiếp đến hiệu quả Cache và tốc độ Build. Kết luận
Có thể ghi nhớ Docker Image bằng bốn từ:
Luồng tổng quát:
Dockerfile
↓
docker build
↓
Docker Image
↓
Registry
↓
docker run
↓
Container
Hiểu Image Layers và Cache là nền tảng để bước sang Dockerfile với các instruction như FROM, RUN, COPY, WORKDIR, ENV, EXPOSE và CMD — những thành phần quyết định cách Docker Image được xây dựng và sử dụng trong CI/CD.
Ở bài trước, chúng ta đã học:
Image là template bất biến (immutable), còn Container là running instance được tạo ra từ Image.
Bài này đi sâu vào cấu trúc Docker Image và cơ chế Layers giúp Docker Build, Pull và Deploy hiệu quả.
1. Docker Image là gì?
Docker Image là một đối tượng immutable, đóng gói Application cùng Dependencies và các chỉ dẫn cần thiết để chạy ứng dụng.
Khác với VM:
Virtual Machine
├── Application
├── Libraries
├── Guest OS
└── Kernel
Docker Image
├── Application
├── Libraries
└── Dependencies
│
▼
Host Kernel
Image không chứa đầy đủ kernel và drivers như VM. Container sử dụng kernel do Host cung cấp.
Vì không phải boot một Guest OS hoàn chỉnh, Container thường khởi động nhanh hơn VM.
2. Vì sao Docker Image nhỏ?
Một Image dựa trên Ubuntu không có nghĩa chứa toàn bộ software như Ubuntu VM.
Minimal Image thậm chí có thể thiếu:
bash
curl
ping
vim
Image chỉ nên chứa những binaries và dependencies mà Application thực sự cần.
Điều này giúp Image nhỏ hơn, phân phối nhanh hơn và giảm các thành phần không cần thiết.
3. Đừng sửa Container – hãy Build Image mới
Giả sử Production chạy:
example-app:1.0
Khi cần thay đổi code hoặc cài thêm dependency, không nên đăng nhập vào Container và sửa trực tiếp.
Cách phù hợp hơn:
Source Code
↓
Modify
↓
docker build
↓
example-app:1.1
↓
Test
↓
Deploy
Như vậy Staging và Production có thể sử dụng cùng một phiên bản Image, giúp duy trì Dev/Prod Parity và hỗ trợ tự động hóa CI/CD.
4. Container nên có tính Ephemeral
Container nên có khả năng:
Stop → Remove → Re-create → Replace
mà không làm mất state quan trọng.
Đây chính là tư tưởng Stateless Processes trong 12-Factor App.
Container
│
└── Application
Persistent State
│
└── External Storage / Database
Dữ liệu quan trọng không nên phụ thuộc vào vòng đời Container. 5. Docker Image được xây dựng từ Layers
Docker Image không phải một khối filesystem duy nhất mà được cấu thành từ nhiều Layers.
Ví dụ:
┌─────────────────────┐
│ Application Code │
├─────────────────────┤
│ Python Dependencies │
├─────────────────────┤
│ Python Runtime │
├─────────────────────┤
│ Ubuntu │
└─────────────────────┘
Một Image có thể sử dụng Image khác làm nền tảng:
Ubuntu 18.04
↓
Python 3.8
↓
example-app:1.0
Ở đây python:3.8 là Parent Image của example-app:1.0.
Image cũng có thể bắt đầu từ:
FROM scratch
scratch đại diện cho điểm bắt đầu trống. 6. Layer Cache – lý do Docker Build nhanh
Các Layer có thể được lưu trong cache và tái sử dụng.
Ubuntu
│
Python
/ \
/ \
App 1.0 App 2.0
Nếu Ubuntu và Python Layers đã tồn tại, Docker không cần tải hoặc lưu lại chúng cho mỗi Image mới.
Điều này giúp:
Build nhanh hơn → Push/Pull hiệu quả hơn → tiết kiệm Storage → CI/CD nhanh hơn.
Nếu chỉ Application Code thay đổi, các Layer trước đó vẫn có thể được tái sử dụng. Nhưng khi một Layer sớm trong quá trình Build thay đổi, các bước phụ thuộc phía sau có thể phải Build lại.
Vì vậy, thứ tự các instruction trong Dockerfile ảnh hưởng trực tiếp đến hiệu quả Cache và tốc độ Build. Kết luận
Có thể ghi nhớ Docker Image bằng bốn từ:
Immutable – Layered – Cached – Reusable
Luồng tổng quát:
Dockerfile
↓
docker build
↓
Docker Image
↓
Registry
↓
docker run
↓
Container
Hiểu Image Layers và Cache là nền tảng để bước sang Dockerfile với các instruction như FROM, RUN, COPY, WORKDIR, ENV, EXPOSE và CMD — những thành phần quyết định cách Docker Image được xây dựng và sử dụng trong CI/CD.