dive: soi từng layer Docker để tìm vì sao image nặng
Tóm tắt
dive cho thấy bên trong từng layer image: file thêm, sửa, xoá, điểm hiệu quả và dung lượng lãng phí. Xoá file phải nằm cùng lệnh RUN tạo ra nó, dùng .dockerignore và multi-stage. Trong CI đặt CI=true.
Image Docker của bạn nặng 1,2 GB trong khi ứng dụng chỉ vài chục MB. Đâu là thủ phạm: cache của trình quản lý gói, file build trung gian, hay một file lớn được copy vào rồi xoá ở layer sau (vẫn chiếm chỗ)? docker history chỉ cho biết kích thước từng layer, không cho biết bên trong có gì. dive cho phép "lặn" vào từng layer: xem cây file của layer, file nào được thêm, sửa, xoá, và tính điểm hiệu quả cùng dung lượng lãng phí của cả image.

Cài đặt
brew install dive
# Hoặc chạy bằng Docker (cần mount socket)
docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock wagoodman/dive myapp:latest
Các bản Linux có gói .deb/.rpm trên trang Releases.
Cách dùng
dive myapp:latest # phân tích image đã có
dive build -t myapp:latest . # build rồi phân tích ngay, thay cho docker build
Màn hình chia hai: bên trái là danh sách layer kèm lệnh Dockerfile tạo ra nó và kích thước; bên dưới là thông tin tổng: điểm hiệu quả (efficiency) và dung lượng lãng phí (wasted space). Bên phải là cây file của layer đang chọn, tô màu file mới thêm, đã sửa, đã xoá.
Phím tắt
| Phím | Tác dụng |
|---|---|
Tab | Chuyển giữa khung layer và khung cây file |
Ctrl+A / Ctrl+L | Ở khung layer: xem thay đổi cộng dồn / chỉ thay đổi của layer hiện tại |
Space, Ctrl+Space | Thu gọn/mở một thư mục, hoặc tất cả |
Ctrl+A, Ctrl+R, Ctrl+M, Ctrl+U | Ở khung cây file: ẩn/hiện file thêm, xoá, sửa, không đổi |
Ctrl+F | Lọc file theo tên |
Ctrl+B | Hiện thuộc tính file |
Q / Ctrl+C | Thoát |
Mẹo: ở khung cây file, tắt hiển thị file không đổi (Ctrl+U) để chỉ thấy những gì layer đó thực sự thêm vào.
Các lỗi phổ biến dive giúp phát hiện
- Xoá ở layer khác:
RUN apt-get install ...rồiRUN rm -rf /var/lib/apt/lists/*ở lệnh sau: file vẫn nằm trong layer trước. Gộp vào cùng một lệnhRUN. - COPY quá nhiều:
COPY . .mang theo.git,node_modules, file test. Thêm.dockerignore. - Công cụ build còn trong image cuối: dùng multi-stage build, chỉ copy artifact sang stage cuối.
- Cache trình quản lý gói: pip, npm cache nằm lại trong image; dùng
--no-cache-dirhoặc dọn trong cùng lệnh.
Dùng trong CI
Đặt CI=true để dive chạy không giao diện và trả kết quả đạt/không đạt theo quy tắc trong file .dive-ci:
# .dive-ci
rules:
lowestEfficiency: 0.95
highestWastedBytes: 20MB
highestUserWastedPercent: 0.20
CI=true dive myapp:latest
Lưu ý
- Điểm hiệu quả cao không có nghĩa image nhỏ; image nền nặng vẫn có thể đạt 99%. Kết hợp với việc chọn base image nhẹ.
- Chạy dive bằng Docker cần mount
docker.sock, tức container có toàn quyền với Docker trên máy.
Áp dụng thế nào?
- Dev: Khi viết Dockerfile mới, dùng
dive buildthay chodocker buildvài lần để thấy ngay layer nào phình to. - Tech Lead/DevOps: Thêm bước
CI=true divevới ngưỡng hợp lý để chặn image lãng phí trước khi đẩy lên registry. - PM: Image nhỏ hơn nghĩa là deploy nhanh hơn, ít tốn băng thông và lưu trữ registry, và ít thành phần có thể chứa lỗ hổng.
Nguồn & tham khảo
- wagoodman/dive — wagoodman (GitHub)