Configure Logrotate on Debian VPS: Full Setup Guide

Why Log Management Matters on a Debian VPS
Left unchecked, log files grow quietly until they cause real problems. A busy web server can generate several gigabytes of access and error logs per week. On a Debian VPS with a modest 50 GB disk, that adds up faster than most people expect — and a full disk will take down your site just as effectively as any hardware failure.
Logrotate is the standard answer. It ships with Debian, runs automatically via cron, and handles rotation, compression, and cleanup with a straightforward configuration syntax. This tutorial walks through a complete setup: understanding the default config, writing custom rules for your own applications, and testing that everything works before you rely on it.
If you are running shared hosting and wondering whether disk pressure is already affecting your site performance, the signs that shared hosting is holding you back are worth reading alongside this guide.
What Logrotate Does (and Does Not Do)
Logrotate rotates log files on a schedule — daily, weekly, or monthly. When a file rotates, the current log gets renamed (for example, access.log becomes access.log.1), a fresh empty file takes its place, and older rotated logs get compressed or deleted depending on your settings.
It does not monitor logs in real time. It does not alert you to errors. It simply keeps the number and size of log files within bounds. For monitoring and alerting on top of that, check out the tutorial on setting up Logwatch daily digests — the same approach applies on Debian.
Step 1 — Verify Logrotate Is Installed
On most Debian 11 and Debian 12 installations, Logrotate is already present. Check with:
logrotate --version
If nothing comes back, install it:
sudo apt update && sudo apt install logrotate -y
Logrotate runs via a daily cron job placed at /etc/cron.daily/logrotate. You can confirm it exists:
ls -l /etc/cron.daily/logrotate
Step 2 — Understand the Default Configuration
The main config file is /etc/logrotate.conf. Open it:
sudo nano /etc/logrotate.conf
A typical Debian default looks like this:
# rotate log files weekly
weekly
# keep 4 weeks of backlogs
rotate 4
# create new (empty) log files after rotating old ones
create
# compress log files
compress
# packages drop log rotation information into this directory
include /etc/logrotate.d
The include /etc/logrotate.d line is the important one. Any file you drop into that directory is automatically picked up and processed. This is where you add rules for Nginx, Apache, MySQL, or any custom application.
Step 3 — Inspect Existing Rules in /etc/logrotate.d
List what is already there:
ls /etc/logrotate.d/
You will typically see entries like nginx, apache2, mysql-server, and dpkg. These ship with their respective packages and cover the most common log paths automatically.
Check the Nginx rule as an example:
cat /etc/logrotate.d/nginx
You will see something like:
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
The postrotate block sends a signal to Nginx so it reopens its log file handles after rotation — essential for processes that keep log files open continuously.
Step 4 — Write a Custom Rule for Your Application
Suppose you are running a PHP application that writes its own logs to /var/www/myapp/logs/app.log. Create a new file in /etc/logrotate.d/:
sudo nano /etc/logrotate.d/myapp
Add the following configuration:
/var/www/myapp/logs/app.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 0664 www-data www-data
sharedscripts
postrotate
# Signal your app to reopen logs if needed
/usr/bin/systemctl reload php8.2-fpm > /dev/null 2>&1 || true
endscript
}
A quick breakdown of the key directives:
- daily — rotate every day rather than waiting for the weekly global default.
- rotate 30 — keep 30 rotated copies before deleting the oldest. For production sites, 30 days of logs is a reasonable audit trail.
- compress — gzip completed log files to reclaim disk space, often reducing size by 80–90%.
- delaycompress — skip compressing the most recent rotated file. Some apps may still be writing to it briefly.
- notifempty — do not rotate the file if it is empty. Avoids cluttering your log directory with zero-byte files.
- missingok — do not throw an error if the log file does not exist yet.
- create 0664 www-data www-data — create the new empty log file with correct ownership immediately after rotation.
Step 5 — Handle Size-Based Rotation
Time-based rotation works well for most sites, but high-traffic applications can produce enormous logs within a single day. In those cases, add a size threshold:
/var/www/myapp/logs/app.log {
size 100M
missingok
rotate 10
compress
delaycompress
notifempty
create 0664 www-data www-data
}
With size 100M, Logrotate will rotate the file as soon as it hits 100 MB regardless of the time schedule. You can combine this with daily using maxsize instead, which rotates on whichever condition triggers first.
Step 6 — Test Without Waiting for Cron
Never assume your config is correct until you test it. Run Logrotate manually in debug mode first:
sudo logrotate --debug /etc/logrotate.d/myapp
Debug mode shows exactly what Logrotate would do without actually doing it. Look for lines like rotating log and compressing log. If there are syntax errors, the output will tell you precisely which line is wrong.
Once that looks correct, force an actual rotation:
sudo logrotate --force /etc/logrotate.d/myapp
After running this, check your log directory:
ls -lh /var/www/myapp/logs/
You should see app.log (the fresh empty file) and app.log.1 (the rotated copy). If compression ran, you will see app.log.1.gz depending on your delaycompress setting.
Step 7 — Check Logrotate Status and History
Logrotate keeps a status file that records when each log was last rotated. On Debian, it lives at /var/lib/logrotate/status. Reading it confirms your rules are being applied on schedule:
cat /var/lib/logrotate/status | grep myapp
If you want to watch the full cron run, check the system journal:
sudo journalctl -u cron --since "1 day ago" | grep logrotate
Step 8 — Set Up Email Alerts for Rotation Errors
By default, Logrotate will log errors to syslog but will not email you. Adding a mail directive sends a notification if rotation fails:
/var/www/myapp/logs/app.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 0664 www-data www-data
mail admin@yourdomain.com
mailFirst
}
The mailFirst directive sends the log file contents after the first rotation, which is useful for review. Use mailLast if you want the final copy just before deletion.
For more structured log monitoring on your Debian VPS, pairing Logrotate with a digest tool gives you better visibility. The tutorial on setting up Logwatch email reports covers this nicely — the configuration is nearly identical on Debian.
Common Problems and Quick Fixes
A few issues come up repeatedly with Logrotate on Debian VPS environments.
Rotation not happening on schedule. Check that /etc/cron.daily/logrotate is executable (ls -l /etc/cron.daily/logrotate) and that your cron daemon is running (systemctl status cron). Also confirm the system clock is correct — VPS instances that have been suspended or migrated sometimes drift.
Log file permissions wrong after rotation. If your application cannot write to the new log file after rotation, the create directive is likely missing or has wrong ownership. Match the user and group to whatever process writes the log.
Postrotate script failing silently. If the service reload in your postrotate block fails, Logrotate still completes the rotation without warning. Test the reload command manually first: sudo systemctl reload php8.2-fpm. If it fails, check service status before wiring it into Logrotate.
Disk still filling despite Logrotate running. Double-check that old compressed archives are actually being deleted. If rotate 30 means you are keeping 30 x 100 MB files, that is still 3 GB of logs. Reduce either the rotation count or the size threshold. For ongoing disk monitoring, the guide on monitoring VPS disk usage with alerts is directly applicable to Debian as well.
Recommended Settings for Common Hosting Scenarios
A quick reference for the most common VPS workloads:
- WordPress / PHP site (low traffic):
weekly, rotate 8, compress— keeps two months of logs without bloat. - WooCommerce or busy PHP app:
daily, rotate 14, compress, maxsize 50M— daily rotation with a size cap prevents surprises during traffic spikes. - MySQL slow query log:
weekly, rotate 4, compress, notifempty— weekly is fine; the slow query log is only active when you enable it deliberately. - Custom Node.js or Python app:
daily, rotate 30, compress, delaycompress— add apostrotateto restart or signal the process.
Running a Debian VPS with growing log files and no clear disk headroom? Hostperl VPS hosting gives you full root access, predictable SSD storage, and APAC-friendly latency so you can manage your stack exactly as this guide describes. If you are outgrowing your current environment, Hostperl dedicated servers are worth a look for sites where disk, RAM, and I/O need to be fully yours.
Frequently Asked Questions
Does Logrotate work differently on Debian compared to Ubuntu or AlmaLinux?
The configuration syntax and file paths are virtually identical across Debian, Ubuntu, and RHEL-family systems. The main differences are package manager commands and, on AlmaLinux, the cron integration may use /etc/cron.d/ rather than /etc/cron.daily/. The logic and directives covered in this guide transfer directly.
Can I rotate logs that a running process has open?
Yes, but you need the postrotate block to signal the process to close and reopen its log file handle. Without this, the process keeps writing to the old (rotated) file descriptor even after rotation. For Nginx, send USR1. For Apache, reload the service. For custom apps, use whatever signal or API your application supports.
How do I rotate logs for a Docker container running on my Debian VPS?
If the container writes logs to a bind-mounted directory on the host (e.g., /var/log/mycontainer/), you can manage those with a standard Logrotate rule on the host. Docker's own logging driver also has built-in rotation options you can set in /etc/docker/daemon.json, which may be simpler for containers that use the default json-file driver.
What is the difference between rotate 0 and removing a Logrotate rule entirely?
rotate 0 means Logrotate rotates the file but immediately deletes it without keeping any backups. This can be useful for logs you want cleared on each rotation but still need the service reload signal to run. Removing the rule entirely means Logrotate ignores that log path altogether and it grows without limit.
