Debugging WordPress in Docker
Learning Objectives
- Enable and configure WordPress debugging in Docker
- Set up Xdebug for step-by-step PHP debugging
- Monitor and analyze container logs
- Troubleshoot common Docker WordPress issues
Introduction
Debugging WordPress in Docker requires understanding both WordPress debugging tools and Docker's logging and inspection capabilities. This lesson covers comprehensive debugging strategies.
Debugging Strategy
WordPress Debug Configuration
Configuring WordPress for comprehensive debugging in Docker:
Debug Constants in docker-compose.yml
# docker-compose.yml
version: '3.8'
services:
wordpress:
image: wordpress:latest
environment:
WORDPRESS_DEBUG: 'true'
WORDPRESS_DEBUG_LOG: 'true'
WORDPRESS_DEBUG_DISPLAY: 'false'
WORDPRESS_CONFIG_EXTRA: |
/* Debugging Configuration */
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
define('SCRIPT_DEBUG', true);
define('SAVEQUERIES', true);
/* Error Reporting */
@ini_set('display_errors', 0);
@ini_set('log_errors', 1);
@ini_set('error_log', '/var/www/html/wp-content/debug.log');
/* Memory and Execution */
define('WP_MEMORY_LIMIT', '256M');
define('WP_MAX_MEMORY_LIMIT', '512M');
@ini_set('max_execution_time', 300);
/* Query Monitoring */
define('QUERY_MONITOR', true);
/* Disable Fatal Error Handler for debugging */
define('WP_DISABLE_FATAL_ERROR_HANDLER', true);
volumes:
- ./wp-content:/var/www/html/wp-content
- ./debug-logs:/var/www/html/wp-content/debug-logs
Custom Debug Helper Plugin
<?php
/**
* Plugin Name: Docker Debug Helper
* Description: Enhanced debugging for WordPress in Docker
*/
// Custom error handler
function docker_debug_error_handler($errno, $errstr, $errfile, $errline) {
$log_entry = sprintf(
"[%s] Error %d: %s in %s on line %d\n",
date('Y-m-d H:i:s'),
$errno,
$errstr,
$errfile,
$errline
);
error_log($log_entry, 3, WP_CONTENT_DIR . '/debug-logs/custom-errors.log');
// Also log to Docker stdout for container logs
error_log($log_entry);
return false; // Let WordPress handle it too
}
set_error_handler('docker_debug_error_handler', E_ALL & ~E_NOTICE);
// Log all database queries
add_action('shutdown', function() {
global $wpdb;
if (defined('SAVEQUERIES') && SAVEQUERIES && $wpdb->queries) {
$log_file = WP_CONTENT_DIR . '/debug-logs/queries.log';
$log_entry = date('[Y-m-d H:i:s] ') . count($wpdb->queries) . " queries\n";
foreach ($wpdb->queries as $query) {
$log_entry .= sprintf(
"Query: %s\nTime: %f\nCaller: %s\n\n",
$query[0],
$query[1],
$query[2]
);
}
error_log($log_entry, 3, $log_file);
}
});
// Memory usage monitoring
add_action('wp_footer', function() {
if (WP_DEBUG && current_user_can('manage_options')) {
$memory = memory_get_peak_usage(true) / 1024 / 1024;
echo "<!-- Peak Memory: {$memory} MB -->";
}
});
Setting Up Xdebug
Configure Xdebug for step-by-step PHP debugging:
Custom Dockerfile with Xdebug
# Dockerfile.debug
FROM wordpress:6.4-php8.2-apache
# Install Xdebug
RUN pecl install xdebug-3.2.0 \
&& docker-php-ext-enable xdebug
# Configure Xdebug
RUN echo "[xdebug]" >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo "xdebug.mode=develop,debug" >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo "xdebug.client_host=host.docker.internal" >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo "xdebug.client_port=9003" >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo "xdebug.start_with_request=yes" >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo "xdebug.log=/var/log/xdebug.log" >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo "xdebug.idekey=PHPSTORM" >> /usr/local/etc/php/conf.d/xdebug.ini
# Install additional debugging tools
RUN apt-get update && apt-get install -y \
vim \
net-tools \
iputils-ping \
telnet \
&& rm -rf /var/lib/apt/lists/*
# Enable Apache modules for debugging
RUN a2enmod rewrite headers expires
# Create log directory
RUN mkdir -p /var/log/xdebug && chmod 777 /var/log/xdebug
Docker Compose with Xdebug
# docker-compose.debug.yml
version: '3.8'
services:
wordpress:
build:
context: .
dockerfile: Dockerfile.debug
container_name: wp-debug
ports:
- "8080:80"
- "9003:9003" # Xdebug port
environment:
WORDPRESS_DEBUG: 'true'
XDEBUG_CONFIG: "client_host=host.docker.internal"
PHP_IDE_CONFIG: "serverName=localhost"
volumes:
- ./wp-content:/var/www/html/wp-content
- ./xdebug-logs:/var/log/xdebug
extra_hosts:
- "host.docker.internal:host-gateway"
Container Log Management
Effective log monitoring and analysis:
graph TD
A[WordPress Container] --> B[Apache Access Logs]
A --> C[Apache Error Logs]
A --> D[PHP Error Logs]
A --> E[WordPress Debug Logs]
A --> F[Xdebug Logs]
G[MySQL Container] --> H[MySQL Error Logs]
G --> I[Slow Query Logs]
B --> J[Docker Logs]
C --> J
D --> J
E --> J
F --> J
H --> J
I --> J
J --> K[Log Analysis]
Centralized Logging Configuration
# docker-compose.logging.yml
version: '3.8'
services:
wordpress:
image: wordpress:latest
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
labels: "service=wordpress"
volumes:
- ./logs/wordpress:/var/log/apache2
- ./logs/php:/var/log/php
mysql:
image: mysql:8.0
command: --general-log=1 --general-log-file=/var/log/mysql/general.log
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
labels: "service=mysql"
volumes:
- ./logs/mysql:/var/log/mysql
# Log aggregator
fluentd:
image: fluent/fluentd:v1.16-1
volumes:
- ./fluentd/conf:/fluentd/etc
- ./logs:/var/log
ports:
- "24224:24224"
Log Monitoring Commands
# View all container logs
docker-compose logs
# Follow WordPress logs
docker-compose logs -f wordpress
# View last 100 lines
docker-compose logs --tail=100
# Filter error messages
docker-compose logs wordpress 2>&1 | grep -i error
# Save logs to file
docker-compose logs > docker-logs-$(date +%Y%m%d).txt
# View WordPress debug.log
docker exec wp-site tail -f /var/www/html/wp-content/debug.log
# Monitor MySQL slow queries
docker exec wp-mysql tail -f /var/log/mysql/slow.log
# Real-time Apache access log
docker exec wp-site tail -f /var/log/apache2/access.log
Common Issues and Solutions
1. White Screen of Death (WSOD)
# Enable display errors temporarily
docker exec wp-site wp config set WP_DEBUG true --raw
docker exec wp-site wp config set WP_DEBUG_DISPLAY true --raw
# Check PHP errors
docker exec wp-site tail -n 50 /var/log/apache2/error.log
# Check memory limit
docker exec wp-site php -r "echo ini_get('memory_limit');"
# Increase memory if needed
docker exec wp-site sh -c "echo 'memory_limit = 512M' > /usr/local/etc/php/conf.d/memory.ini"
docker-compose restart wordpress
2. Database Connection Errors
# Test database connection
docker exec wp-site wp db check
# Verify credentials
docker exec wp-site wp config get DB_HOST
docker exec wp-site wp config get DB_NAME
docker exec wp-site wp config get DB_USER
# Test MySQL connectivity
docker exec wp-site apt-get update && apt-get install -y mysql-client
docker exec wp-site mysql -h mysql -u wpuser -p wordpress -e "SELECT 1"
# Check network connectivity
docker network inspect wordpress_default
docker exec wp-site ping mysql
3. Permission Issues
# Check file ownership
docker exec wp-site ls -la /var/www/html/wp-content
# Fix ownership
docker exec wp-site chown -R www-data:www-data /var/www/html/wp-content
# Fix permissions
docker exec wp-site find /var/www/html/wp-content -type d -exec chmod 755 {} \;
docker exec wp-site find /var/www/html/wp-content -type f -exec chmod 644 {} \;
# Make uploads writable
docker exec wp-site chmod 775 /var/www/html/wp-content/uploads
Performance Debugging
Identifying and resolving performance issues:
Query Monitor Setup
# Install Query Monitor plugin
docker exec wp-site wp plugin install query-monitor --activate
# Enable for debugging
docker exec wp-site wp config set QM_ENABLE true --raw
docker exec wp-site wp config set QM_DARK_MODE true --raw
Performance Monitoring Script
<?php
// performance-monitor.php
// Place in wp-content/mu-plugins/
add_action('wp_footer', function() {
if (!current_user_can('manage_options')) return;
$stats = [
'queries' => get_num_queries(),
'time' => timer_stop(0, 3),
'memory' => size_format(memory_get_peak_usage(true)),
'included_files' => count(get_included_files()),
];
echo "<!-- Performance Stats:\n";
foreach ($stats as $key => $value) {
echo " {$key}: {$value}\n";
}
echo "-->";
});
// Log slow queries
add_filter('query', function($query) {
$start = microtime(true);
add_filter('query_results', function($results) use ($query, $start) {
$time = microtime(true) - $start;
if ($time > 0.05) { // Log queries taking more than 50ms
error_log(sprintf(
"Slow Query (%.3fs): %s",
$time,
$query
));
}
return $results;
}, 10, 1);
return $query;
});
Debugging Best Practices
- Separate debug environment:Use a dedicated Docker setup for debugging
- Version control debug configs:Keep debug configurations in separate files
- Log rotation:Implement log rotation to prevent disk space issues
- Security:Never enable debug mode in production
- Performance impact:Disable Xdebug when not actively debugging
- Documentation:Document common issues and solutions for your team
Real World Example: Debug Workflow
Complete debugging setup for development:
#!/bin/bash
# debug-setup.sh
echo "Setting up WordPress debugging environment..."
# 1. Start containers with debug configuration
docker-compose -f docker-compose.yml -f docker-compose.debug.yml up -d
# 2. Install debugging plugins
docker exec wp-site wp plugin install query-monitor --activate
docker exec wp-site wp plugin install debug-bar --activate
docker exec wp-site wp plugin install log-deprecated-notices --activate
# 3. Create debug user
docker exec wp-site wp user create debugger debug@example.com \
--role=administrator \
--user_pass=debug123
# 4. Enable all debug flags
docker exec wp-site wp config set WP_DEBUG true --raw
docker exec wp-site wp config set WP_DEBUG_LOG true --raw
docker exec wp-site wp config set WP_DEBUG_DISPLAY false --raw
docker exec wp-site wp config set SCRIPT_DEBUG true --raw
docker exec wp-site wp config set SAVEQUERIES true --raw
# 5. Create log monitoring script
cat > watch-logs.sh << 'EOF'
#!/bin/bash
echo "Monitoring WordPress logs..."
echo "Press Ctrl+C to stop"
# Use multitail if available, otherwise fall back to tail
if command -v multitail &> /dev/null; then
multitail \
-l "docker exec wp-site tail -f /var/www/html/wp-content/debug.log" \
-l "docker-compose logs -f wordpress" \
-l "docker exec wp-mysql tail -f /var/log/mysql/error.log"
else
docker exec wp-site tail -f /var/www/html/wp-content/debug.log &
docker-compose logs -f wordpress &
wait
fi
EOF
chmod +x watch-logs.sh
echo "Debug environment ready!"
echo "Access WordPress at: http://localhost:8080"
echo "Query Monitor available for admin users"
echo "Run ./watch-logs.sh to monitor logs"
Practice Exercise
Set up and practice debugging techniques:
Try It Now