🔵 Docker Image
Template bất biến (read-only). Chứa code, dependencies, OS files. Xây từ Dockerfile.
🟢 Docker Container
Instance đang chạy của image. Có state, writable layer. Tạo/xóa nhanh.
1. Ví Dụ Dễ Hiểu
🏭 Ví dụ:
Image = Bản vẽ thiết kế (blueprint) của một căn nhà. Bạn có thể xây nhiều căn
nhà GIỐNG NHAU từ 1 bản vẽ.
Container = Căn nhà đã xây xong, có người ở. Mỗi căn nhà có đồ đạc (state)
riêng, nhưng cấu trúc giống nhau.
2. Docker Image
# Dockerfile → tạo Image
FROM node:20-alpine # Layer 1: Base OS + Node.js
WORKDIR /app # Layer 2: Set working dir
COPY package*.json ./ # Layer 3: Copy package files
RUN npm ci --production # Layer 4: Install deps
COPY . . # Layer 5: Copy source code
EXPOSE 3000
CMD ["node", "server.js"] # Default command
Image Layers (read-only, cached):
┌─────────────────────────┐
│ Layer 5: Source code │ ← thay đổi thường xuyên
│ Layer 4: npm modules │ ← cached nếu package.json không đổi
│ Layer 3: package.json │
│ Layer 2: WORKDIR /app │
│ Layer 1: node:20-alpine │ ← base image (OS + runtime)
└─────────────────────────┘
→ Tất cả layers đều READ-ONLY
→ Layers được CACHE → rebuild nhanh
# Build image từ Dockerfile
docker build -t myapp:1.0 .
# Xem danh sách images
docker images
# REPOSITORY TAG IMAGE ID SIZE
# myapp 1.0 abc123def 150MB
# node 20 xyz789ghi 350MB
# Push image lên registry
docker push myregistry/myapp:1.0
3. Docker Container
Container = Image + Writable Layer + Runtime:
┌─────────────────────────┐
│ Writable Layer (state) │ ← logs, temp files, data
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ Layer 5: Source code │
│ Layer 4: npm modules │ ← Image layers (read-only)
│ Layer 3: package.json │
│ Layer 2: WORKDIR /app │
│ Layer 1: node:20-alpine │
└─────────────────────────┘
Container 1 ─┐
Container 2 ─┤── CÙNG Image, KHÁC writable layer
Container 3 ─┘
# Tạo container từ image
docker run -d --name web1 -p 3000:3000 myapp:1.0
docker run -d --name web2 -p 3001:3000 myapp:1.0
docker run -d --name web3 -p 3002:3000 myapp:1.0
# → 3 containers từ CÙNG 1 image!
# Xem containers đang chạy
docker ps
# CONTAINER ID IMAGE PORTS NAMES
# a1b2c3 myapp:1.0 0.0.0.0:3000->3000 web1
# d4e5f6 myapp:1.0 0.0.0.0:3001->3000 web2
# g7h8i9 myapp:1.0 0.0.0.0:3002->3000 web3
# Stop & remove container (image vẫn còn)
docker stop web1
docker rm web1
# Container bị xóa → writable layer MẤT
# Dùng volumes để persist data:
docker run -v ./data:/app/data myapp:1.0
4. Bảng So Sánh
| Tiêu chí | 🔵 Image | 🟢 Container |
|---|---|---|
| Bản chất | Template (blueprint) | Instance đang chạy |
| State | Bất biến (immutable) | Có state (writable layer) |
| Tạo bởi | docker build | docker run |
| Lưu trữ | Registry (Docker Hub, ECR) | Docker host (local) |
| Số lượng | 1 image → nhiều containers | Mỗi container = 1 instance |
| Lifecycle | Persist vĩnh viễn | Ephemeral (tạo/xóa nhanh) |
| Chia sẻ | Push/pull qua registry | Không chia sẻ trực tiếp |
| Layers | Read-only layers | Read-only + writable layer |
5. Tổng Kết
Workflow:
1. Viết Dockerfile (recipe)
2. docker build → tạo Image
3. docker push → đẩy Image lên registry
4. docker run → tạo Container từ Image
5. Container chạy app, dùng volumes cho data persistence