Skip to main content

Course Progress

Loading...

Debugging WordPress in Docker

Duration: 50 minutes
Module 4: Session 5.5

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
Effective debugging combines WordPress debug constants, Docker logs, Xdebug for PHP, and browser developer tools for a complete debugging toolkit.

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
  1. Enable WordPress debug mode in your Docker setup
  2. Create a plugin with an intentional error
  3. View the error in debug.log:docker exec wp-site tail -f /var/www/html/wp-content/debug.log
  4. Install Query Monitor:docker exec wp-site wp plugin install query-monitor --activate
  5. Monitor container logs:docker-compose logs -f
  6. Check resource usage:docker stats
  7. Test database queries:docker exec wp-site wp db query "SHOW TABLES"
  8. Fix the intentional error and verify the fix

Additional Resources