Quay lại danh sách
Tin tức công nghệ

Tối ưu hóa dung lượng Docker: Tự động dọn dẹp Build Cache và Dangling Images trên VPS qua Systemd Timer

4 tháng 6, 2026

1. Đặt vấn đề: Cuộc chiến giành giật tài nguyên lưu trữ trên VPS

Trong kỷ nguyên của kiến trúc vi dịch vụ (microservices) và quy trình CI/CD, Docker đã trở thành một công cụ không thể thiếu đối với các nhà phát triển và quản trị hệ thống. Khả năng đóng gói ứng dụng và nhất quán môi trường giúp việc triển khai trở nên nhanh chóng hơn bao giờ hết. Tuy nhiên, sự tiện lợi này đi kèm với một cái giá không hề nhỏ về mặt tài nguyên lưu trữ, đặc biệt là trên các máy chủ ảo cá nhân (VPS) vốn có dung lượng ổ đĩa hạn chế.

Sau một thời gian vận hành và liên tục cập nhật ứng dụng, bạn có thể nhận thấy dung lượng trống trên VPS sụt giảm một cách báo động. Khi chạy lệnh kiểm tra, thủ phạm thường không ai khác chính là hệ thống Docker. Hai yếu tố chiếm dụng không gian lưu trữ âm thầm và mạnh mẽ nhất chính là: Docker Build Cache và các Dangling Images (hình ảnh treo). Nếu không có biện pháp can thiệp kịp thời, ổ đĩa bị đầy sẽ dẫn đến tình trạng treo dịch vụ, sập cơ sở dữ liệu và làm gián đoạn toàn bộ hệ thống kinh doanh của doanh nghiệp.

2. Hiểu rõ kẻ thù: Dangling Images và Build Cache là gì?

Để tối ưu hóa một cách an toàn, trước tiên chúng ta cần hiểu rõ bản chất của những thành phần đang chiếm dụng tài nguyên.

Dangling Images là gì?

Dangling Images (thường hiển thị là : khi bạn chạy lệnh docker images) là các hình ảnh đã mất liên kết với bất kỳ container nào đang hoạt động hoặc bất kỳ thẻ (tag) nào. Hiện tượng này thường xảy ra khi bạn build một bản dựng mới của Image với cùng một tên và tag cũ. Docker sẽ gán tag đó cho bản dựng mới, khiến bản dựng cũ trở thành "mồ côi". Chúng không còn giá trị sử dụng nhưng vẫn bám chặt lấy ổ cứng của bạn.

Docker Build Cache là gì?

Kể từ khi tích hợp BuildKit, Docker tối ưu hóa thời gian đóng gói bằng cách lưu lại bộ đệm của các bước build trước đó (Build Cache). Điều này giúp các lần build sau diễn ra cực kỳ nhanh chóng vì Docker chỉ cần tải lại các layer không có sự thay đổi. Tuy nhiên, qua hàng chục hoặc hàng trăm lần cập nhật mã nguồn, lượng cache này phình to ra một cách khủng khiếp, đôi khi lên tới hàng chục Gigabyte, vượt xa kích thước thực tế của ứng dụng đang chạy.

3. Tại sao giải pháp thủ công và Cronjob truyền thống là chưa đủ?

Nhiều quản trị viên hệ thống thường xử lý vấn đề này bằng cách thỉnh thoảng truy cập vào VPS và gõ lệnh docker system prune một cách thủ công. Phương pháp này mang tính đối phó và rất dễ bị lãng quên cho đến khi hệ thống gửi cảnh báo "No space left on device".

Một giải pháp nâng cấp hơn là sử dụng Cronjob. Mặc dù Cronjob rất phổ biến, nhưng trong môi trường Linux hiện đại, nó bộc lộ một số hạn chế cốt lõi khi quản lý các tác vụ dọn dẹp hệ thống nặng:

  • Thiếu kiểm soát ràng buộc: Cronjob sẽ kích hoạt bất kể hệ thống đang ở trạng thái nào. Nếu VPS của bạn đang bị quá tải CPU do lượng truy cập tăng đột biến, Cronjob vẫn sẽ chạy lệnh dọn dẹp Docker, đẩy hệ thống vào trạng thái sập hoàn toàn.
  • Ghi log kém: Việc quản lý log của Cronjob khá phân tán và khó theo dõi trực quan nếu không cấu hình chuyển hướng log phức tạp.
  • Không có tính năng quản lý phụ thuộc: Bạn không thể thiết lập để lệnh dọn dẹp chỉ chạy sau khi một dịch vụ khác đã hoàn thành an toàn.

4. Giải pháp tối ưu: Tự động hóa bằng Systemd Timer

Để giải quyết triệt để các nhược điểm của Cronjob, Systemd Timer là sự thay thế hoàn hảo được tích hợp sẵn trong hầu hết các bản phân phối Linux hiện đại (Ubuntu, CentOS, Debian). Systemd Timer mang lại khả năng quản lý tác vụ định kỳ một cách mạnh mẽ, an toàn và dễ dàng giám sát thông qua journalctl.

Quy trình triển khai hệ thống dọn dẹp tự động bao gồm 2 bước chính: Tạo một Systemd Service để định nghĩa hành động dọn dẹp, và tạo một Systemd Timer để định nghĩa tần suất kích hoạt.

Bước 1: Tạo Systemd Service để thực thi lệnh dọn dẹp Docker

Chúng ta sẽ tạo một file dịch vụ cấu hình cho tác vụ dọn dẹp. Hãy tạo file mới tại đường dẫn sau:

sudo nano /etc/systemd/system/docker-cleanup.service

Sau đó, thêm nội dung cấu hình dưới đây vào file:

[Unit]
Description=Docker Cleanup Service
After=docker.service
Requires=docker.service

[Service]
Type=oneshot
ExecStart=/usr/bin/docker system prune -f --volumes

[Install]
WantedBy=multi-user.target
Giải thích cấu hình: Lệnh docker system prune -f --volumes sẽ xóa bỏ toàn bộ dangling images, build cache và các volume không còn sử dụng mà không yêu cầu xác nhận thủ công (nhờ tham số -f). Thuộc tính After=docker.service đảm bảo dịch vụ này chỉ chạy khi Docker đã khởi động thành công.

Bước 2: Tạo Systemd Timer để lập lịch tự động

Tiếp theo, chúng ta tạo bộ định thời để kích hoạt dịch vụ trên định kỳ (ví dụ: vào lúc 3 giờ sáng Chủ nhật hàng tuần, thời điểm lượng truy cập vào VPS thường thấp nhất). Tạo file timer bằng lệnh:

sudo nano /etc/systemd/system/docker-cleanup.timer

Nhập nội dung cấu hình sau:

[Unit]
Description=Run Docker Cleanup Weekly

[Timer]
OnCalendar=Sun *-*-* 03:00:00
Persistent=true

[Install]
WantedBy=timers.target
Giải thích cấu hình: Tham số OnCalendar=Sun *-*-* 03:00:00 thiết lập lịch chạy cụ thể. Đặc biệt, thuộc tính Persistent=true cực kỳ quan trọng: nếu VPS của bạn bị tắt nguồn đúng vào lúc 3 giờ sáng Chủ nhật, Systemd sẽ ngay lập tức bù lại bằng cách chạy tác vụ ngay khi máy chủ được bật lại, điều mà Cronjob không bao giờ làm được.

Bước 3: Kích hoạt và kiểm tra hệ thống

Sau khi đã chuẩn bị xong hai file cấu hình, bạn cần nạp lại cấu hình hệ thống và kích hoạt Timer bằng các lệnh sau:

  1. Nạp lại cấu hình Systemd: sudo systemctl daemon-reload
  2. Kích hoạt và cho phép Timer chạy cùng hệ thống: sudo systemctl enable --now docker-cleanup.timer

Để kiểm tra danh sách các bộ hẹn giờ đang hoạt động và biết chính xác khi nào lệnh dọn dẹp Docker sẽ chạy tiếp theo, hãy sử dụng lệnh:

systemctl list-timers --all

5. Giám sát và quản lý Log dọn dẹp hệ thống

Một trong những lý do khiến các chuyên gia Devops ưa chuộng Systemd là khả năng quản lý log tập trung tuyệt vời thông qua journalctl. Để kiểm tra xem tiến trình dọn dẹp Docker đã hoạt động ra sao, giải phóng được bao nhiêu dung lượng, bạn chỉ cần gõ lệnh:

sudo journalctl -u docker-cleanup.service

Hệ thống sẽ hiển thị chi tiết kết quả trả về từ lệnh Docker, giúp bạn dễ dàng theo dõi sức khỏe của VPS và hiệu quả của việc tối ưu hóa mà không cần phải cài đặt thêm bất kỳ công cụ bên thứ ba nào.

6. Kết luận

Việc tối ưu hóa dung lượng lưu trữ trên VPS là một nhiệm vụ liên tục và quan trọng đối với bất kỳ doanh nghiệp nào nhằm đảm bảo tính ổn định cao nhất cho hệ thống. Bằng cách kết hợp sức mạnh của lệnh dọn dẹp Docker và cơ chế lập lịch thông minh của Systemd Timer, bạn đã xây dựng thành công một lá chắn tự động bảo vệ VPS khỏi nguy cơ cạn kiệt bộ nhớ. Hãy áp dụng giải pháp này ngay hôm nay để giải phóng tài nguyên hệ thống và an tâm tập trung vào việc phát triển sản phẩm kinh doanh cốt lõi của mình.