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.