Your server has been running fine for three months. Then one morning nothing works — SSH is slow, services throw errors, disk at 100%.

df -h

You dig in and find /var/log is 40GB. One log file has been growing unchecked since day one. logrotate ships on every Debian/Ubuntu server. Most people ignore it until it bites them.

Find what's eating your disk right now

sudo du -sh /var/log/* | sort -rh | head -20

If you find a multi-GB file with no rotation config, fix it today. Don't wait for a 3am alert.

How it works

logrotate runs daily via cron (/etc/cron.daily/logrotate). It reads /etc/logrotate.conf and everything in /etc/logrotate.d/. Drop a file there for each app you want to manage.

ls /etc/logrotate.d/

nginx, rsyslog, apt — probably already there. Check what nginx is doing: cat /etc/logrotate.d/nginx

Write your own config

App writing to /var/log/myapp/app.log:

/var/log/myapp/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 0640 www-data www-data
    sharedscripts
    postrotate
        systemctl reload myapp 2>/dev/null || true
    endscript
}

What each option does:

  • daily — rotate every day. weekly and monthly also valid.
  • rotate 14 — keep 14 old files, delete the rest
  • compress — gzip rotated files
  • delaycompress — don't compress the most recent rotated file (some apps keep it open)
  • missingok — don't error if the log file is missing
  • notifempty — skip rotation if the file is empty
  • create 0640 www-data www-data — create a new empty log file with these permissions after rotation
  • postrotate — reload the app so it starts writing to the new file

Test before you trust it

sudo logrotate -d /etc/logrotate.d/myapp

-d is dry run — shows what would happen without doing it. If it says "log does not need rotating" that's fine, it's just not due yet.

Force a rotation now:

sudo logrotate -f /etc/logrotate.d/myapp

The postrotate gotcha that burns everyone

If your app doesn't get reloaded after rotation, it keeps writing to the old (now rotated) file. The new empty log stays empty. Logs go to the rotated copy. This catches people constantly.

Always add a postrotate that reloads your app or sends SIGHUP:

postrotate
    kill -HUP $(cat /var/run/myapp.pid) 2>/dev/null || true
endscript

The || true prevents logrotate from erroring if the service isn't running.

Global defaults

/etc/logrotate.conf sets defaults for everything. Individual configs in /etc/logrotate.d/ override per-app.

cat /etc/logrotate.conf

Cap journald too

systemd's journal accumulates separately. Check and cap it:

sudo journalctl --disk-usage
sudo nano /etc/systemd/journald.conf
[Journal]
SystemMaxUse=500M
MaxRetentionSec=1month
sudo systemctl restart systemd-journald

Combined, logrotate + a journald cap keeps /var/log under control permanently.


Related posts