Tools

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.

Trang GitHub của wagoodman/dive
Trang GitHub của wagoodman/dive (ảnh chụp tháng 11/2026)

GitHub: https://github.com/wagoodman/dive · khoảng 55 nghìn sao · Go · MIT

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ímTác dụng
TabChuyể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+SpaceThu 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+FLọc file theo tên
Ctrl+BHiện thuộc tính file
Q / Ctrl+CThoá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ồi RUN 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ệnh RUN.
  • 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-dir hoặ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 build thay cho docker build vài lần để thấy ngay layer nào phình to.
  • Tech Lead/DevOps: Thêm bước CI=true dive vớ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

  1. wagoodman/dive — wagoodman (GitHub)