Khoá học ngắn về Docker

Docker: cache của layer và kích thước ảnh

Hai câu hỏi mà mọi người dựng ảnh Docker đều gặp: vì sao build lại mất ba phút khi tôi chỉ sửa một dòng mã, và vì sao ảnh vẫn nặng sau khi tôi đã rm đống file tạm. Cả hai đều có câu trả lời chính xác, và cả hai đều đo được bằng chính docker build với docker image inspect. Số liệu trong khoá lấy từ Docker 29.7.2 với BuildKit (buildx v0.36.1).

Hai bài, hai con số đáng nhớ Sửa dòng RUN đầu tiên trong một Dockerfile sáu bước làm năm bước sau nó chạy lại. Và một ảnh tạo 20 MB rồi xoá ở lệnh RUN tiếp theo đo được 25 104 035 byte — lớn hơn 463 byte so với chính ảnh đó khi giữ nguyên file.

Lộ trình

Mỗi bài khoảng 12–15 phút đọc, kèm phòng thí nghiệm chạy ngay trên trình duyệt.

Cách đo

Bộ đo là một thư mục build nhỏ và một script chạy docker build đúng một lần cho mỗi kịch bản, rồi đọc dòng CACHED trong log. Chi tiết này quan trọng: bản script đầu tiên chạy build hai lần, và lần thứ hai luôn báo mọi bước đều CACHED — bảng kết quả khi đó toàn số 100% cache và hoàn toàn vô nghĩa.

DOCKER_BUILDKIT=1 docker build -t dlab:t ctx > /tmp/b.log 2>&1
awk '/^#[0-9]+ \[[0-9]+\/[0-9]+\]/ { … }
     /^#[0-9]+ CACHED/ { … }' /tmp/b.log

docker image inspect dsize:hai --format '{{.Size}}'
# 25104035

Kích thước ảnh lấy từ docker image inspect --format '{{.Size}}' chứ không phải cột SIZE của docker image ls. Hai lệnh cho hai con số khác nhau: với kho ảnh containerd đang dùng ở đây, docker image ls báo 55,3 MB cho chính ảnh mà inspect báo 25 104 035 byte, vì nó cộng cả blob nén lẫn bản giải nén trong kho. Bài học chỉ dùng số của inspect và nói rõ lệnh nào sinh ra con số nào.