logrotate and journald: Managing WordPress and Nginx Log Rotation

Without log rotation, WordPress debug logs and Nginx/Apache access logs can grow until they fill the disk. logrotate handles file-based logs while systemd-journald handles service logs — both need explicit configuration for a production WordPress server.

Problem: A WordPress server accumulates unbounded log files — Nginx access logs, PHP-FPM logs, WordPress debug logs — that fill disk space over time and make diagnosing issues harder because relevant entries are buried in months of output.

Solution: Configure logrotate with a weekly rotation policy, 4-week retention, and postrotate hook to signal Nginx to reopen log files. For systemd-managed services, configure journald persistence and size limits in /etc/systemd/journald.conf to complement file-based log rotation.

The examples below configure logrotate for the WordPress debug log and Nginx access/error logs, and set journal size limits and log forwarding for PHP-FPM.

# /etc/logrotate.d/wordpress
/var/www/html/wp-content/debug.log {
    daily                   # rotate every day
    rotate 14               # keep 14 rotated files
    compress                # gzip old files
    delaycompress           # compress on the second rotation
    missingok               # no error if file doesn't exist
    notifempty              # skip rotation if file is empty
    create 0640 www-data www-data
    postrotate
        # Send USR1 to PHP-FPM to re-open log files
        /bin/kill -USR1 $(cat /run/php/php8.2-fpm.pid 2>/dev/null) 2>/dev/null || true
    endscript
}

# /etc/logrotate.d/nginx  (adjust paths for your distro)
/var/log/nginx/*.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    sharedscripts
    postrotate
        nginx -s reopen 2>/dev/null || true
    endscript
}

# Test the config without actually rotating:
logrotate --debug /etc/logrotate.d/wordpress

Limit journal size and forward PHP-FPM logs to the journal:

# /etc/systemd/journald.conf
[Journal]
SystemMaxUse=500M        # total journal disk usage
SystemKeepFree=1G        # always leave 1 GB free
MaxRetentionSec=30day    # delete entries older than 30 days
MaxFileSec=1week         # rotate journal file weekly

# Apply without reboot:
systemctl restart systemd-journald

# Forward PHP-FPM stderr to the journal — /etc/php/8.2/fpm/pool.d/www.conf:
; catch_workers_output = yes
; decorate_workers_output = no
; error_log = /proc/self/fd/2   ; writes to systemd journal via stderr

# View WordPress-related journal entries:
journalctl -u php8.2-fpm -u nginx --since "1 hour ago" | grep -i "wordpress\|wp-cron\|fatal"

# Vacuum old journal entries immediately:
journalctl --vacuum-time=30d
journalctl --vacuum-size=200M

NOTE: Enable WordPress debug logging conditionally — never leave WP_DEBUG_LOG on in production. Use a custom log path outside the web root and rotate it with logrotate as shown above.

Leave Comment

Your email address will not be published. Required fields are marked *