Set Up Logrotate for Server Logs on Ubuntu VPS: Complete Guide

By Raman Kumar

Share:

Updated on May 13, 2026

Set Up Logrotate for Server Logs on Ubuntu VPS: Complete Guide

Why Your VPS Logs Are Eating Disk Space

Server logs grow fast. Apache, Nginx, MySQL, and system logs can consume gigabytes monthly without proper management. When your VPS hosting runs out of space, sites crash and databases lock.

Logrotate solves this by automatically compressing old logs, deleting ancient ones, and keeping your system running smoothly. This tutorial shows you how to set up logrotate properly on Ubuntu VPS servers.

Understanding Logrotate Basics

Logrotate runs daily via cron and processes log files according to rules you define. It can rotate logs based on size, age, or both. When logs rotate, logrotate creates new files and handles old ones according to your retention policy.

Ubuntu ships with logrotate pre-installed and basic configurations for system logs. Web servers, databases, and applications often need custom rules though.

Check if logrotate is running:

sudo systemctl status cron
sudo cat /etc/cron.daily/logrotate

The daily cron job should show logrotate scheduled to run automatically.

Configure Logrotate for Apache Logs

Apache generates access and error logs for each virtual host. Without rotation, these files grow indefinitely.

Create a custom Apache logrotate configuration:

sudo nano /etc/logrotate.d/apache2-custom

Add this configuration:

/var/log/apache2/*.log {
    daily
    missingok
    rotate 52
    compress
    delaycompress
    notifempty
    create 640 www-data adm
    sharedscripts
    postrotate
        if /bin/systemctl status apache2 > /dev/null ; then \
            /bin/systemctl reload apache2; \
        fi;
    endscript
}

This rotates Apache logs daily, keeps 52 weeks of history, compresses old logs, and reloads Apache after rotation. The delaycompress option keeps yesterday's log uncompressed for applications that might still write to it.

Test your Apache configuration:

sudo logrotate -d /etc/logrotate.d/apache2-custom

The -d flag runs in debug mode without actually rotating files, showing what would happen.

Set Up Nginx Log Rotation

Nginx logs need similar treatment but with different reload commands. Create an Nginx-specific configuration:

sudo nano /etc/logrotate.d/nginx-custom

Configure Nginx log rotation:

/var/log/nginx/*.log {
    daily
    missingok
    rotate 52
    compress
    delaycompress
    notifempty
    create 644 www-data adm
    sharedscripts
    prerotate
        if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
            run-parts /etc/logrotate.d/httpd-prerotate; \
        fi; \
    endscript
    postrotate
        invoke-rc.d nginx rotate >/dev/null 2>&1
    endscript
}

Nginx requires a special signal to reopen log files. The invoke-rc.d nginx rotate command sends the proper USR1 signal to the Nginx master process.

For custom Nginx log locations, add them specifically:

/var/www/*/logs/*.log {
    daily
    rotate 30
    compress
    missingok
    notifempty
    sharedscripts
    postrotate
        invoke-rc.d nginx rotate >/dev/null 2>&1
    endscript
}

Configure MySQL and MariaDB Log Rotation

Database logs require careful handling because MySQL and MariaDB need to know when logs rotate.

Create a database-specific configuration:

sudo nano /etc/logrotate.d/mysql-custom

Add MySQL log rotation rules:

/var/log/mysql/*.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    sharedscripts
    postrotate
        /usr/bin/mysqladmin --defaults-file=/etc/mysql/debian.cnf flush-logs
    endscript
}

The flush-logs command tells MySQL to close current log files and open new ones. This ensures clean log rotation without data loss.

For MariaDB systems, the configuration is identical but verify the debian.cnf path:

ls -la /etc/mysql/debian.cnf

If you've configured custom database logs, our MySQL slow query log tutorial shows how to handle performance log rotation properly.

Handle Application-Specific Logs

Applications often create logs in custom locations. PHP applications, Node.js services, and custom scripts need their own rotation rules.

Create application log rotation:

sudo nano /etc/logrotate.d/applications

Configure rotation for common application logs:

# PHP application logs
/var/www/*/logs/*.log {
    weekly
    rotate 12
    compress
    missingok
    notifempty
    create 644 www-data www-data
}

# Custom application logs
/opt/*/logs/*.log {
    daily
    rotate 7
    compress
    missingok
    notifempty
    copytruncate
}

# System service logs
/var/log/custom/*.log {
    daily
    rotate 30
    compress
    missingok
    notifempty
    create 640 root root
}

The copytruncate option copies the log file and truncates the original instead of moving it. This works well for applications that keep log files open continuously.

Test and Debug Logrotate Configuration

Always test configurations before relying on them in production. Logrotate provides several debugging options to verify your setup.

Test specific configuration files:

sudo logrotate -d /etc/logrotate.d/apache2-custom
sudo logrotate -d /etc/logrotate.d/nginx-custom
sudo logrotate -d /etc/logrotate.conf

Force immediate rotation for testing:

sudo logrotate -f /etc/logrotate.d/apache2-custom

The -f flag forces rotation regardless of file size or age. Use this to verify your configuration works correctly.

Check logrotate status:

sudo cat /var/lib/logrotate/status

This file shows when each log was last rotated, helping you troubleshoot timing issues.

Monitor logrotate execution:

sudo tail -f /var/log/syslog | grep logrotate

Advanced Configuration Options

Beyond basic rotation, logrotate offers advanced features for complex hosting environments. Size-based rotation prevents logs from growing too large between scheduled rotations.

Configure size-based rotation:

/var/log/hightraffic/*.log {
    size 100M
    rotate 10
    compress
    missingok
    notifempty
    create 644 www-data adm
    sharedscripts
    postrotate
        /bin/systemctl reload apache2
    endscript
}

Use conditional rotation based on file age and size:

/var/log/mixed/*.log {
    daily
    size 50M
    maxage 90
    rotate 30
    compress
    missingok
    notifempty
}

The maxage directive deletes files older than specified days regardless of rotation count.

For email logs that need special handling, our Postfix mail queue management guide covers rotation strategies for mail server logs.

Managing server logs properly requires reliable VPS infrastructure. Hostperl's managed VPS hosting includes pre-configured log rotation and monitoring to keep your servers running smoothly without manual intervention.

Monitor Disk Usage and Log Growth

Set up monitoring to catch log growth issues before they cause problems.

Create a simple script to check log directory sizes:

sudo nano /usr/local/bin/check-log-sizes.sh

Add this monitoring script:

#!/bin/bash

# Check log directory sizes
echo "Log Directory Usage Report - $(date)"
echo "=========================================="

for dir in /var/log/apache2 /var/log/nginx /var/log/mysql /var/www/*/logs; do
    if [ -d "$dir" ]; then
        size=$(du -sh "$dir" 2>/dev/null | cut -f1)
        echo "$dir: $size"
    fi
done

echo ""
echo "Largest log files:"
find /var/log /var/www/*/logs -name "*.log" -type f -exec ls -lh {} + 2>/dev/null | sort -k5 -hr | head -10

Make the script executable and run it:

sudo chmod +x /usr/local/bin/check-log-sizes.sh
sudo /usr/local/bin/check-log-sizes.sh

Add this to cron for weekly reports:

sudo crontab -e

Add the cron entry:

0 9 * * 1 /usr/local/bin/check-log-sizes.sh | mail -s "Weekly Log Size Report" admin@yourdomain.com

Troubleshooting Common Issues

When logrotate doesn't work as expected, several issues commonly occur.

Permission problems prevent logrotate from creating new files or accessing log directories. Fix them with:

sudo chown www-data:adm /var/log/apache2/*.log
sudo chmod 640 /var/log/apache2/*.log

Missing log directories cause rotation failures:

sudo mkdir -p /var/log/custom
sudo chown root:adm /var/log/custom
sudo chmod 755 /var/log/custom

Service reload failures happen when services aren't running or can't reload. Check service status before rotation:

sudo systemctl status apache2
sudo systemctl status nginx
sudo systemctl status mysql

Lock file issues prevent logrotate from running. Remove stale lock files:

sudo rm -f /var/lib/logrotate/lock

For hosting environments with custom security configurations, our UFW firewall guide shows how to secure log directories while maintaining proper access.

Frequently Asked Questions

How often should I rotate logs on a production VPS?

Most production servers should rotate logs daily for high-traffic applications and weekly for low-traffic sites. Keep 30-90 days of compressed logs for troubleshooting and compliance requirements.

What happens if logrotate fails during cron execution?

Logrotate logs errors to syslog and continues processing other configurations. Check /var/log/syslog for error messages and use the status file to see which logs were processed successfully.

Can I rotate logs based on file size instead of time?

Yes, use the "size" directive instead of "daily" or "weekly". For example, "size 100M" rotates when files exceed 100 megabytes. You can combine size and time limits for more control.

How do I handle logs for applications that keep files open?

Use the "copytruncate" option for applications that don't handle log rotation signals. This copies the log file and truncates the original, allowing the application to continue writing.

Should I compress rotated logs immediately?

Use "delaycompress" to keep yesterday's log uncompressed. Some applications or monitoring tools may still access recent log files. Older logs get compressed during the next rotation cycle.