How to Enable Xdebug in Laravel Sail for Step Debugging

How to Enable Xdebug in Laravel Sail for Step Debugging

Laravel Sail makes development with Docker incredibly simple, but when you need to debug complex middleware issues or step through your code, Xdebug becomes essential. Here’s how to properly configure Xdebug in your Laravel Sail environment.

Why You Need Xdebug

While dd() and Log::info() are great for basic debugging, sometimes you need to:

  • Step through code line by line
  • Inspect variable values in real-time
  • Understand complex execution flows (like middleware ordering)
  • Debug hard-to-reproduce issues

Method 1: Permanent Setup (Recommended)

This approach modifies your Sail configuration permanently and is the best option for ongoing development.

Step 1: Publish Sail’s Docker Files

First, publish the Sail Docker files so you can customize them:

php artisan sail:publish

This creates a docker/ directory with the Docker configurations that you can now modify.

Step 2: Configure Environment Variables

Add these variables to your .env file:

SAIL_XDEBUG_MODE=develop,debug,coverage
SAIL_XDEBUG_CONFIG="client_host=host.docker.internal"

Important Notes:

  • host.docker.internal works on macOS and Windows
  • On Linux, you might need to use 172.17.0.1 or your host IP instead

Step 3: Rebuild Your Containers

Rebuild your containers with Xdebug enabled:

sail down
sail build --no-cache
sail up -d

The --no-cache flag ensures a fresh build with your new configuration.

Method 2: Quick Temporary Setup

If you need Xdebug right now and don’t want to rebuild everything:

# Access the Sail container
sail shell

# Install Xdebug
apt-get update
apt-get install php8.4-xdebug

# Create Xdebug configuration
echo "zend_extension=xdebug.so
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal
xdebug.client_port=9003
xdebug.log=/tmp/xdebug.log" >> /etc/php/8.4/cli/conf.d/99-xdebug.ini

# Copy to FPM config as well
cp /etc/php/8.4/cli/conf.d/99-xdebug.ini /etc/php/8.3/fpm/conf.d/

# Restart PHP-FPM
service php8.4-fpm restart

Note: This method won’t persist if you rebuild your containers.

IDE Configuration

Visual Studio Code

Create .vscode/launch.json in your project root:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for Xdebug",
            "type": "php",
            "request": "launch",
            "port": 9003,
            "pathMappings": {
                "/var/www/html": "${workspaceFolder}"
            },
            "ignore": [
                "**/vendor/**/*.php"
            ]
        }
    ]
}

Make sure you have the PHP Debug extension installed.

PhpStorm

  1. Configure Xdebug Port:
    • Go to Settings → PHP → Debug
    • Set Xdebug port to 9003
    • Uncheck “Break at first line in PHP scripts”
  2. Configure Server:
    • Go to Settings → PHP → Servers
    • Click the + button to add a new server
    • Name: laravel-sail
    • Host: localhost
    • Port: 80 (or whatever port your Sail app uses)
    • Debugger: Xdebug
    • Check “Use path mappings”
    • Map your project root to /var/www/html
  3. Set up Run Configuration:
    • Go to Run → Edit Configurations
    • Click + and select PHP Web Page
    • Name: Laravel Sail Debug
    • Server: Select the server you created above
    • Start URL: / (or whatever route you want to debug)

Verify Xdebug is Working

Check PHP Configuration

sail artisan tinker

Then run:

phpinfo();

Look for an “xdebug” section in the output. You should see something like:

xdebug support => enabled
Version => 3.2.0

Test with a Simple Breakpoint

  1. Set a breakpoint in a route or controller method
  2. Start listening for Xdebug connections in your IDE
  3. Access the route in your browser
  4. Your IDE should pause at the breakpoint

Common Troubleshooting

Xdebug Not Connecting

Problem: IDE shows “Waiting for incoming connection with ide key…”

Solutions:

  • Check that port 9003 is not blocked by your firewall
  • On Linux, try using your host IP instead of host.docker.internal
  • Verify the pathMappings in your IDE configuration

Wrong PHP Version

Problem: Installing the wrong Xdebug version for your PHP version.

Solution: Check your PHP version first:

sail php --version

Then install the matching Xdebug package (e.g., php8.4-xdebug for PHP 8.4).

Path Mapping Issues

Problem: Breakpoints show as “invalid” or debugging doesn’t work.

Solution: Ensure your IDE path mappings are correct:

  • Local path: Your project root directory
  • Remote path: /var/www/html

Performance Considerations

Xdebug can slow down your application significantly. For production-like performance testing:

# Temporarily disable Xdebug
sail shell
php -d xdebug.mode=off artisan your:command

Or modify your .env:

SAIL_XDEBUG_MODE=off

Then rebuild your containers.

Advanced Configuration

Custom Xdebug Settings

If you need custom Xdebug settings, modify the published Docker files in docker/8.4/xdebug.ini:

zend_extension=xdebug.so
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal
xdebug.client_port=9003
xdebug.log=/var/log/xdebug.log
xdebug.log_level=7
xdebug.max_nesting_level=512

Debugging Artisan Commands

To debug Artisan commands, you might need to trigger Xdebug manually:

sail php -d xdebug.start_with_request=yes artisan your:command

With Xdebug properly configured in Laravel Sail, you can step through your code, inspect variables, and understand complex execution flows. This is particularly valuable when debugging middleware ordering issues, complex business logic, or hard-to-reproduce bugs.

The permanent setup method is recommended for ongoing development, while the temporary method is perfect for quick debugging sessions. Choose the approach that best fits your workflow and start debugging like a pro!

Quick Reference Commands

# Publish Sail files
php artisan sail:publish

# Rebuild with Xdebug
sail down && sail build --no-cache && sail up -d

# Check if Xdebug is loaded
sail php -m | grep xdebug

# Test Xdebug configuration
sail php -i | grep xdebug

Leave a Reply