Cấu hình logrotate quản lý log trên VPS Ubuntu

Khi chạy một VPS trong thời gian dài, các file log của hệ thống và ứng dụng (Nginx, MySQL, Docker) âm thầm phình to, có thể chiếm hàng GB ổ đĩa. Nếu bạn không có kế hoạch dọn dẹp, một ngày đẹp trời bạn sẽ không SSH vào được vì ổ / đã đầy. Logrotate là công cụ có sẵn trên Ubuntu giúp bạn tự động hóa việc này: nén log cũ, xoay vòng theo thời gian, và xóa log quá hạn. Bài này hướng dẫn bạn cấu hình logrotate trên VPS Ubuntu 24.04 để quản lý log hiệu quả, giữ hệ thống luôn khỏe mạnh.
Yêu cầu trước khi bắt đầu
- Một VPS chạy VPS Linux với Ubuntu 24.04 LTS (hướng dẫn tương thích Ubuntu 22.04, Debian 12).
- Quyền truy cập root hoặc user sudo.
- Các dịch vụ đã cài đặt (Nginx, MySQL, Docker…) đang chạy để thực hành.
- Biết các lệnh cơ bản:
nano,ls,cat.
Logrotate là gì và cơ chế hoạt động
Logrotate là daemon chạy định kỳ (mặc định mỗi ngày một lần qua cron) để xử lý các file log dựa trên cấu hình trong /etc/logrotate.conf và các file trong thư mục /etc/logrotate.d/. Cấu hình cơ bản gồm:
- rotate: số file log cũ giữ lại (vd
rotate 7). - daily/weekly/monthly: tần suất xoay.
- compress: nén file bằng gzip.
- delaycompress: trì hoãn nén 1 lần xoay (để ứng dụng kịp ghi tiếp).
- missingok: không báo lỗi nếu file log chưa có.
- notifempty: không xoay nếu file log rỗng.
- postrotate: script chạy sau khi xoay log (vd reload Nginx).
Khi xoay, /var/log/nginx/access.log thành access.log.1, sau đó nén thành access.log.1.gz, rồi lần sau thành access.log.2.gz…, đến số rotate thì file cũ nhất bị xóa.
Kiểm tra logrotate đã được cài đặt chưa
Trên Ubuntu, logrotate được cài mặc định. Hãy kiểm tra:
sudo logrotate --versionNếu chưa có, cài đặt:
sudo apt update && sudo apt install logrotate -yVERIFY: chạy lệnh và xem trạng thái cronjob:
sudo systemctl status logrotate.timerKết quả hiển thị active (waiting) nghĩa là timer đang chờ lịch chạy.
Bước 1 - Tìm hiểu cấu hình logrotate mặc định của hệ thống
File cấu hình chính: /etc/logrotate.conf. Xem nội dung:
sudo cat /etc/logrotate.confMột số dòng quan trọng:
rotate 4
weekly
create
compress
include /etc/logrotate.d
/var/log/wtmp {
missingok
monthly
create 0664 root utmp
rotate 1
}Giải thích: mặc định xoay hàng tuần, giữ 4 file cũ, nén, bao gồm các cấu hình riêng trong /etc/logrotate.d/. Hãy xem thư mục đó chứa gì:
ls -l /etc/logrotate.d/Bạn sẽ thấy các file như apt, dpkg, rsyslog, ufw… Mỗi file là cấu hình riêng cho một dịch vụ.
Bước 2 - Cấu hình logrotate cho Nginx
Giả sử Nginx được cài mặc định, log nằm ở /var/log/nginx/access.log và error.log. Tạo file cấu hình riêng:
sudo nano /etc/logrotate.d/nginxDán nội dung sau:
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}Giải thích:
- daily: xoay mỗi ngày.
- rotate 14: giữ log 14 ngày gần nhất.
- sharedscripts: chỉ chạy script postrotate một lần cho tất cả file trong block.
- kill -USR1: gửi tín hiệu yêu cầu Nginx mở lại file log mới (không reload cả service).
VERIFY cấu hình có đúng cú pháp không:
sudo logrotate -d /etc/logrotate.d/nginxNếu không có lỗi error, cấu hình hợp lệ. Chạy thử (force) để xem hoạt động:
sudo logrotate -f /etc/logrotate.d/nginxLúc này /var/log/nginx/access.log sẽ được xoay thành access.log.1. Kiểm tra:
ls -la /var/log/nginx/Bước 3 - Cấu hình logrotate cho MySQL (MariaDB)
Log của MySQL thường ở /var/log/mysql/error.log và /var/log/mysql/mysql-slow.log. Tạo file:
sudo nano /etc/logrotate.d/mysql/var/log/mysql/*.log {
daily
missingok
rotate 7
compress
delaycompress
notifempty
create 640 mysql adm
sharedscripts
postrotate
if [ -x /usr/bin/mysqladmin ] && [ -f /var/run/mysqld/mysqld.pid ]; then
/usr/bin/mysqladmin --defaults-file=/etc/mysql/debian.cnf flush-logs 2>/dev/null
fi
endscript
}Lưu ý: lệnh flush-logs yêu cầu MySQL đóng log cũ và mở file mới. Đường dẫn đến mysqld.pid có thể khác tùy bản (Ubuntu 24.04 dùng MariaDB, pid ở /run/mysqld/).
VERIFY:
sudo logrotate -d /etc/logrotate.d/mysql
sudo logrotate -f /etc/logrotate.d/mysql # chạy thửBước 4 - Cấu hình logrotate cho Docker container log
Log của Docker container (json-file driver) nằm ở /var/lib/docker/containers/*/*.log. Cỡ file có thể lên tới vài GB nếu không quản lý. Tạo file cấu hình:
sudo nano /etc/logrotate.d/docker-containers/var/lib/docker/containers/*/*.log {
rotate 7
daily
compress
missingok
delaycompress
copytruncate
}Giải thích: copytruncate là chìa khóa, nó copy file log sang file mới, rồi truncate (xóa nội dung) file gốc mà không cần kill/reload container. Docker không support USR1 dễ dàng, nên copytruncate là giải pháp an toàn.
VERIFY:
sudo logrotate -d /etc/logrotate.d/docker-containersBước 5 - Kiểm tra và debug logrotate tổng thể
Sau khi cấu hình xong, logrotate chạy tự động qua timer. Bạn có thể chạy thủ công để kiểm tra toàn bộ:
sudo logrotate -v -f /etc/logrotate.confTham số -v in chi tiết từng bước. Xem log của logrotate:
sudo cat /var/log/logrotate.logNếu thấy lỗi (vd permission denied), kiểm tra quyền user sở hữu file log và tham số create.
Mẹo debug: nếu log không xoay, hãy kiểm tra trạng thái của file, logrotate chỉ xoay nếu file có nội dung và đã cũ hơn 1 chu kỳ (daily thì cũ hơn 1 ngày). Thử xóa dòng notifempty để buộc xoay ngay cả file rỗng.
Xử lý lỗi thường gặp
Lỗi "error: skipping because parent directory has insecure permissions"
Logrotate không xoay vì thư mục /var/log/nginx/ có permission quá lỏng lẻo (vd 777). Khắc phục: set lại owner và permission:
sudo chown root:adm /var/log/nginx
sudo chmod 750 /var/log/nginxLỗi web server không ghi log sau khi xoay
Khi dùng copytruncate (như Docker), file gốc bị truncate nhưng ứng dụng vẫn giữ file descriptor cũ, nên vẫn ghi tiếp. Nếu dùng create + kill signal mà web server vẫn ghi vào file cũ, hãy kiểm tra script postrotate có chạy đúng không:
sudo journalctl -u logrotate.service --since "5 minutes ago"Logrotate không chạy đúng lịch
Kiểm tra timer systemd có active không:
sudo systemctl list-timers --all | grep logrotateNếu timer disabled, enable nó:
sudo systemctl enable --now logrotate.timerCâu hỏi thường gặp
Có thể xoay log mỗi giờ không?
Có. Thay daily bằng hourly, nhưng cần cấu hình cron chạy mỗi giờ: copy file /lib/systemd/system/logrotate.timer thành /etc/systemd/system/ và sửa OnCalendar=hourly. Tuy nhiên, xoay quá thường xuyên có thể gây mất mát dữ liệu log nếu ứng dụng không kịp xử lý tín hiệu.
Sự khác giữa compress và delaycompress là gì?
compress nén file log ngay sau khi xoay. delaycompress trì hoãn nén đến lần xoay tiếp theo, ứng dụng vẫn cần ghi tiếp vào file cũ giây lát sau khi xoay, delaycompress giúp tránh lỗi "file đang được ghi". Nên dùng delaycompress cho dịch vụ ghi log liên tục.
Làm sao để xóa log cũ ngay lập tức?
Chạy lệnh logrotate với tham số -f (force) và --force-rotate:
sudo logrotate -f /etc/logrotate.d/nginxLưu ý: tham số rotate trong cấu hình quyết định số file giữ lại, nên sau khi xoay, file cũ sẽ bị xóa nếu vượt quá số rotate.
Logrotate có ảnh hưởng đến hiệu năng VPS không?
Rất ít. Quá trình chạy nhanh (vài giây) và chỉ chạy mỗi ngày một lần. Với nhiều dịch vụ lớn (cả trăm GB log), nén có thể gây CPU spike nhẹ, nhưng không đáng kể với VPS có 2-4 vCPU. Các gói thuê VPS NVMe phổ biến đều xử lý vượt trội.
Bài viết liên quan
- Tối ưu Nginx cho traffic cao: Worker, Gzip, Buffer, Cache
- Hướng dẫn cấu hình UFW firewall cơ bản trên Ubuntu VPS
- Cách cài Docker trên VPS Ubuntu chi tiết từ A đến Z
- Benchmark hiệu năng VPS với FIO, Sysbench, iperf3


