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
- Configure Xdebug Port:
- Go to
Settings → PHP → Debug
- Set Xdebug port to
9003
- Uncheck “Break at first line in PHP scripts”
- Go to
- 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
- Go to
- Set up Run Configuration:
- Go to
Run → Edit Configurations
- Click
+
and selectPHP Web Page
- Name:
Laravel Sail Debug
- Server: Select the server you created above
- Start URL:
/
(or whatever route you want to debug)
- Go to
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
- Set a breakpoint in a route or controller method
- Start listening for Xdebug connections in your IDE
- Access the route in your browser
- 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