🚀 Chapter 4 — Production: Phần B — Quản lý Docker Image với Amazon ECR Lifecycle Policy
Ở Chapter 4A, chúng ta đã thay đổi kiến trúc:
GitHub
↓
GitHub Actions
↓
Matrix
↓
Reusable Workflow
↓
Docker Build
↓
Amazon ECR
↓
SSH
↓
EC2
↓
docker pull
↓
Docker Compose
EC2 không còn phải build Docker image nữa.
Nhưng khi CI/CD chạy nhiều lần, ECR sẽ bắt đầu có rất nhiều image:
frontend
├── image-001
├── image-002
├── image-003
├── image-004
├── image-005
├── ...
└── image-100
Nếu mỗi lần git push đều tạo một image mới, số lượng image sẽ tăng liên tục.
Vì vậy ở Chapter 4B, chúng ta sẽ giải quyết vấn đề:
Image nào cần giữ lại? Image nào có thể tự động xóa?
AWS ECR cung cấp Lifecycle Policy để tự động expire hoặc archive các image không còn cần thiết. Policy có thể dựa trên số lượng image hoặc thời gian kể từ khi image được push.
1. Mục tiêu
Sau Chapter 4B, kiến trúc sẽ trở thành:
Developer
↓
git push
↓
GitHub
↓
GitHub Actions
↓
Matrix
↓
Reusable Workflow
↓
Docker Build
↓
Amazon ECR
↓
Lifecycle Policy
↓
Old Images → Expire
Mục tiêu của chúng ta:
✅ Image mới vẫn được push vào ECR
✅ Image đang sử dụng vẫn được giữ
✅ Image cũ tự động được cleanup
✅ Không cần SSH vào EC2 để xóa image
✅ Không cần xóa image thủ công
2. Kiểm tra trạng thái từ Chapter 4A
Trên local:
cd online-boutique-cicd
Kiểm tra Git:
git status
Kiểm tra workflow:
find .github/workflows -type f
Bạn sẽ thấy:
.github/workflows/
├── reusable-ci-cd.yml
└── scale-ci-cd.yml
Kiểm tra AWS region:
aws configure get region
Kết quả:
ap-northeast-1
Nếu chưa có:
aws configure set region ap-northeast-1
3. Kiểm tra các ECR Repository
Chạy:
aws ecr describe-repositories \
--query 'repositories[].repositoryName' \
--output table
Bạn sẽ thấy các repository đã tạo ở Chapter 4A:
------------------------------------------------
| DescribeRepositories |
+----------------------------------------------+
| online-boutique-frontend |
| online-boutique-cartservice |
| online-boutique-productcatalogservice |
| online-boutique-checkoutservice |
+----------------------------------------------+
Nếu chỉ muốn kiểm tra riêng Online Boutique:
aws ecr describe-repositories \
--query 'repositories[?starts_with(repositoryName, `online-boutique-`)].repositoryName' \
--output table
4. Kiểm tra Docker Images trong ECR
Kiểm tra frontend:
aws ecr list-images \
--repository-name online-boutique-frontend \
--output table
Nếu workflow Chapter 4A đã chạy nhiều lần, bạn sẽ thấy:
IMAGE TAG
--------
abc123
def456
ghi789
...
Kiểm tra thời gian push:
aws ecr describe-images \
--repository-name online-boutique-frontend \
--query 'imageDetails[].{Tag:imageTags[0],Pushed:imagePushedAt}' \
--output table
Ví dụ:
--------------------------------
| DescribeImages |
+----------+-------------------+
| Tag | Pushed |
+----------+-------------------+
| abc123 | 2026-09-11... |
| def456 | 2026-09-10... |
| ghi789 | 2026-09-09... |
+----------+-------------------+
5. Tạo Lifecycle Policy đầu tiên
Chúng ta sẽ bắt đầu bằng một policy đơn giản:
Giữ lại 5 image được push gần nhất, các image cũ hơn sẽ được expire.
Tạo file:
mkdir -p ecr
nano ecr/lifecycle-policy.json
Thêm:
{
"rules": [
{
"rulePriority": 1,
"description": "Keep only the latest 5 images",
"selection": {
"tagStatus": "any",
"countType": "imageCountMoreThan",
"countNumber": 5
},
"action": {
"type": "expire"
}
}
]
}
Lưu file.
6. Kiểm tra JSON
Chạy:
cat ecr/lifecycle-policy.json
Bạn phải thấy:
{
"rules": [
{
"rulePriority": 1,
"description": "Keep only the latest 5 images",
"selection": {
"tagStatus": "any",
"countType": "imageCountMoreThan",
"countNumber": 5
},
"action": {
"type": "expire"
}
}
]
}
Nếu máy có jq:
jq . ecr/lifecycle-policy.json
Nếu chưa có:
sudo apt install -y jq
7. Preview Lifecycle Policy
Không áp dụng policy ngay.
Trước tiên chúng ta preview để xem image nào sẽ bị expire.
AWS cũng khuyến nghị sử dụng lifecycle policy preview trước khi áp dụng policy thực tế.
Chạy:
aws ecr start-lifecycle-policy-preview \
--repository-name online-boutique-frontend \
--lifecycle-policy-text file://ecr/lifecycle-policy.json
Kết quả sẽ trả về:
previewId
repositoryName
status
Ví dụ:
{
"registryId": "123456789012",
"repositoryName": "online-boutique-frontend",
"lifecyclePolicyText": "...",
"status": "IN_PROGRESS",
"previewId": "..."
}
8. Kiểm tra Preview
Chạy:
aws ecr get-lifecycle-policy-preview \
--repository-name online-boutique-frontend
Ban đầu có thể:
IN_PROGRESS
Chờ vài giây rồi chạy lại:
aws ecr get-lifecycle-policy-preview \
--repository-name online-boutique-frontend
Khi hoàn tất:
COMPLETE
9. Xem Image nào sẽ bị xóa
Chạy:
aws ecr get-lifecycle-policy-preview \
--repository-name online-boutique-frontend \
--query 'previewResults[].{Tag:imageTags[0],Action:action,ImageDigest:imageDigest}' \
--output table
Ví dụ:
------------------------------------------------
| GetLifecyclePolicyPreview |
+----------+----------+------------------------+
| Tag | Action | ImageDigest |
+----------+----------+------------------------+
| abc123 | EXPIRE | sha256:... |
| def456 | EXPIRE | sha256:... |
| ghi789 | KEEP | sha256:... |
| jkl012 | KEEP | sha256:... |
| mno345 | KEEP | sha256:... |
+----------+----------+------------------------+
Đây là bước rất quan trọng.
Chúng ta kiểm tra policy trước khi cho phép ECR thực sự expire image.
10. Áp dụng Lifecycle Policy
Sau khi preview đúng với mong muốn:
aws ecr put-lifecycle-policy \
--repository-name online-boutique-frontend \
--lifecycle-policy-text file://ecr/lifecycle-policy.json
Kết quả:
{
"registryId": "123456789012",
"repositoryName": "online-boutique-frontend",
"lifecyclePolicyText": "..."
}
AWS hỗ trợ tạo hoặc cập nhật lifecycle policy bằng put-lifecycle-policy.
11. Kiểm tra Lifecycle Policy
Chạy:
aws ecr get-lifecycle-policy \
--repository-name online-boutique-frontend
Hoặc chỉ lấy policy:
aws ecr get-lifecycle-policy \
--repository-name online-boutique-frontend \
--query 'lifecyclePolicyText' \
--output text
Kết quả:
{
"rules": [
{
"rulePriority": 1,
"description": "Keep only the latest 5 images",
"selection": {
"tagStatus": "any",
"countType": "imageCountMoreThan",
"countNumber": 5
},
"action": {
"type": "expire"
}
}
]
}
12. Áp dụng cho các service còn lại
Hiện tại Online Boutique có:
online-boutique-frontend
online-boutique-cartservice
online-boutique-productcatalogservice
online-boutique-checkoutservice
Không nên chỉ quản lý frontend.
Chúng ta áp dụng cùng policy cho tất cả repository.
Chạy:
for repo in \
online-boutique-frontend \
online-boutique-cartservice \
online-boutique-productcatalogservice \
online-boutique-checkoutservice
do
aws ecr put-lifecycle-policy \
--repository-name "$repo" \
--lifecycle-policy-text file://ecr/lifecycle-policy.json
done
Kiểm tra:
for repo in \
online-boutique-frontend \
online-boutique-cartservice \
online-boutique-productcatalogservice \
online-boutique-checkoutservice
do
echo "===== $repo ====="
aws ecr get-lifecycle-policy \
--repository-name "$repo" \
--query 'repositoryName' \
--output text
done
Kết quả:
===== online-boutique-frontend =====
online-boutique-frontend
===== online-boutique-cartservice =====
online-boutique-cartservice
===== online-boutique-productcatalogservice =====
online-boutique-productcatalogservice
===== online-boutique-checkoutservice =====
online-boutique-checkoutservice
13. Kiểm tra số lượng Image
Frontend:
aws ecr describe-images \
--repository-name online-boutique-frontend \
--query 'length(imageDetails)'
Cartservice:
aws ecr describe-images \
--repository-name online-boutique-cartservice \
--query 'length(imageDetails)'
Product catalog:
aws ecr describe-images \
--repository-name online-boutique-productcatalogservice \
--query 'length(imageDetails)'
Checkout:
aws ecr describe-images \
--repository-name online-boutique-checkoutservice \
--query 'length(imageDetails)'
Lưu ý:
Không kỳ vọng image cũ biến mất ngay lập tức.
ECR lifecycle policy thực hiện expire/archive theo cơ chế của ECR; AWS ghi rõ các image bị policy tác động sẽ được expire hoặc archive trong vòng 24 giờ sau khi policy được áp dụng.
14. Tạo thêm image để kiểm tra
Bây giờ chúng ta test thực tế.
Sửa một file bất kỳ:
echo "### Chapter 4B test" >> README.md
Commit:
git add README.md
git commit -m "test ecr lifecycle policy"
git push origin main
GitHub Actions sẽ chạy:
GitHub
↓
Matrix
↓
Reusable Workflow
↓
Docker Build
↓
ECR
Image mới được push:
ECR
│
├── image-old
├── image-old
├── image-old
├── image-old
├── image-old
└── image-new
Lifecycle Policy sẽ đảm bảo repository không giữ image vô hạn.
15. Kiểm tra GitHub Actions
Vào:
GitHub
→ Repository
→ Actions
→ Scale CI/CD
Bạn sẽ thấy:
Scale CI/CD
├── frontend
├── cartservice
├── productcatalogservice
└── checkoutservice
Mỗi service:
Docker Build
↓
Docker Push
↓
ECR
Sau Chapter 4B:
Docker Build
↓
ECR
↓
Lifecycle Policy
↓
Old Image Cleanup
16. Kiểm tra trên AWS Console
Vào:
AWS Console
→ ECR
→ Repositories
→ online-boutique-frontend
Sau đó:
Lifecycle policies
Bạn sẽ thấy rule:
Rule priority: 1
Description:
Keep only the latest 5 images
Image status:
Any
Match criteria:
Image count more than 5
Action:
Expire
AWS Console cũng cho phép tạo lifecycle rule theo image status, tag pattern/prefix và image count hoặc thời gian.
17. Cấu trúc project sau Chapter 4B
Project hiện tại:
online-boutique-cicd/
│
├── .github/
│ └── workflows/
│ ├── reusable-ci-cd.yml
│ └── scale-ci-cd.yml
│
├── ecr/
│ └── lifecycle-policy.json
│
├── src/
│
├── docker-compose.yaml
│
└── README.md
18. Kiến trúc sau Chapter 4B
Chúng ta đã đi từ:
Chapter 3D
GitHub
↓
Matrix
↓
Reusable Workflow
↓
Docker Build
↓
SSH
↓
EC2
↓
Docker Compose Build
↓
Docker Compose Up
Chapter 4A
GitHub
↓
Matrix
↓
Reusable Workflow
↓
Docker Build
↓
ECR
↓
SSH
↓
EC2
↓
Docker Pull
↓
Docker Compose Up
Chapter 4B
GitHub
↓
Matrix
↓
Reusable Workflow
↓
Docker Build
↓
ECR
↓
Lifecycle Policy
↓
Old Images → Expire
↓
SSH
↓
EC2
↓
Docker Pull
↓
Docker Compose Up
19. Kết quả đạt được
Sau Chapter 4B:
✅ Docker image được build ngoài EC2
✅ Image được lưu tập trung trong ECR
✅ Mỗi microservice có repository riêng
✅ ECR tự động quản lý image cũ
✅ Không cần SSH vào EC2 để cleanup
✅ Không để ECR tăng image vô hạn
✅ Đã bắt đầu có artifact management
Và quan trọng nhất:
Chapter 3
──────────────
How do we build many services?
↓
Reusable CI/CD
Chapter 4A
──────────────
Where do we store artifacts?
↓
Amazon ECR
Chapter 4B
──────────────
How do we manage old artifacts?
↓
ECR Lifecycle Policy
Chapter 4C tiếp theo sẽ giải quyết câu hỏi lớn hơn:
Image đã được lưu trong ECR
↓
Nhưng...
↓
Image này có an toàn không?
↓
Có CVE không?
↓
Có vulnerability Critical/High không?
↓
Có cho phép deploy không?
→ Amazon ECR + Amazon Inspector + Image Security Scanning.
All Rights Reserved