The Problem
Application logs grow indefinitely. Without rotation, they fill your disk and can take down your entire server.
How Logrotate Works
Logrotate runs daily via cron and processes config files in /etc/logrotate.d/.
Default Configuration
cat /etc/logrotate.conf
Key directives:
| Directive | Meaning |
|---|---|
daily / weekly / monthly |
Rotation frequency |
rotate 14 |
Keep 14 rotated files |
compress |
Gzip old log files |
delaycompress |
Compress on next rotation (not immediately) |
missingok |
Don't error if log file is missing |
notifempty |
Don't rotate if file is empty |
create 0640 www-data www-data |
Permissions for new log file |
copytruncate |
Truncate original file instead of moving it |
postrotate / endscript |
Run command after rotation |
Custom Application Config
# /etc/logrotate.d/myapp
/var/www/myapp/logs/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 deploy deploy
sharedscripts
postrotate
systemctl reload myapp > /dev/null 2>&1 || true
endscript
}
Nginx Logs
# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
endscript
}
Testing Configuration
# Dry run — see what would happen
sudo logrotate -d /etc/logrotate.d/myapp
# Force rotation now (for testing)
sudo logrotate -f /etc/logrotate.d/myapp
Size-Based Rotation
/var/log/myapp.log {
size 100M # Rotate when file exceeds 100MB
rotate 5
compress
copytruncate # For apps that can't reopen log files
}
Warning Always use
copytruncatefor applications that hold log files open and don't support SIGHUP/USR1 reload signals. Otherwise the app will keep writing to the old (now renamed) file.