Skip to content

Commit

Permalink
Simplify xdebug configuration, fixes #736, fixes #735 (#785)
Browse files Browse the repository at this point in the history
  • Loading branch information
rfay committed May 2, 2018
1 parent d2fde7d commit 38209b6
Show file tree
Hide file tree
Showing 17 changed files with 114 additions and 67 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ VERSION_VARIABLES = DdevVersion WebImg WebTag DBImg DBTag RouterImage RouterTag
# These variables will be used as the default unless overridden by the make
DdevVersion ?= $(VERSION)
WebImg ?= drud/nginx-php-fpm-local
WebTag ?= v1.2.2
WebTag ?= v1.3.0
DBImg ?= drud/mariadb-local
DBTag ?= v0.9.0
RouterImage ?= drud/ddev-router
Expand Down
Binary file modified docs/users/images/atom_cson_config.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed docs/users/images/netbeans_debugger_port.png
Binary file not shown.
Binary file removed docs/users/images/netbeans_project_name_location.png
Binary file not shown.
Binary file not shown.
Binary file modified docs/users/images/phpstorm_config_server_config.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed docs/users/images/phpstorm_debug_port.png
Binary file not shown.
Binary file added docs/users/images/vscode_debug_button.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/users/images/vscode_run_listen_xdebug.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 1 addition & 2 deletions docs/users/snippets/atom_config_cson_snippet.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"php-debug":
PathMaps: [
"remotepath;localpath"
"/var/www/html/docroot;/Users/<change_me_to_correct_path>/<changeme>/<changeme>/docroot"
"/var/www/html;/Users/<change_me_to_correct_path>/<changeme>/<changeme>"
]
ServerPort: 11011
10 changes: 10 additions & 0 deletions docs/users/snippets/vscode_listen_for_xdebug_snippet.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "Listen for XDebug",
"type": "php",
"request": "launch",
"port": 9000,
"pathMappings": {
"/var/www/html": "${workspaceRoot}"
}

},
116 changes: 53 additions & 63 deletions docs/users/step-debugging.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@

Every ddev project is automatically configured with xdebug so that popular IDEs can do step-debugging of PHP code. It is disabled by default for performance reasons, so you'll need to enable it in your config.yaml.

xdebug is a server-side tool: It is installed automatically on the container and you do *not* need to install it on your workstation. All you have to do on your workstation is to add an extra IP address (below) and perhaps add a browser extension or bookmark.
xdebug is a server-side tool: It is installed automatically on the container and you do *not* need to install it on your workstation.

All IDEs basically work the same: They listen on a port and react when they're contacted there. So IDEs other than those listed here should work fine, if listening on port 11011.
All IDEs basically work the same: They listen on a port and react when they're contacted there. So IDEs other than those listed here should work fine, if listening on the default xdebug port 9000.

**Key facts:**
* You need to explicitly enable xdebug in your config.yaml as a post-start step.
* The debug server port on the IDE must be set to port 11011. Although the xdebug default is port 9000, that port often has conflicts for PHP developers, so 11011 is used with ddev.
* An IP-address *alias* of 172.28.99.99 must be added to your workstation host's loopback address. On macOS this is done with the command `sudo ifconfig lo0 alias 172.28.99.99`. On Ubuntu 16.04 and probably other Linux variants, `sudo ifconfig docker0:0 172.28.99.99 up` **This must currently be done after each reboot.**
* You need to explicitly enable xdebug in your config.yaml with `xdebug_enabled: true` (it's disabled by default). After changing, `ddev start` again.
* The debug server port on the IDE must be set to port 9000, which is the default and is probably already set in most IDEs. (If you need to change the xdebug port due to a port conflict on your host computer, you can do it with a PHP override, explained below.)

For more background on XDebug see [XDebug documentation](https://xdebug.org/docs/remote). The intention here is that one won't have to understand XDebug to do debugging.

Expand All @@ -19,49 +18,43 @@ For each IDE the link to their documentation is provided, and the skeleton steps

### Enable or disable xdebug in your config.yaml

Use a post-start hook to enable or disable xdebug on startup:
Enable xdebug in your config.yaml:

```
hooks:
post-start:
- exec: enable_xdebug
```
`xdebug_enabled: true`

(If you don't want it set all the time, you can `ddev exec enable_xdebug` or `ddev exec disable_xdebug` any time.)

### Setup for Various IDEs

* [PHPStorm](#phpstorm)
* [NetBeans](#netbeans)
* [Atom](#atom)
* [Visual Studio Code (vscode)](#vscode)


<a name="phpstorm"></a>
### PHPStorm Debugging Setup

[PHPStorm](https://www.jetbrains.com/phpstorm/download) is a leading PHP development IDE with extensive built-in debugging support. It provides two different ways to do debugging. One requires very little effort in the PHPStorm IDE (they call it zero-configuration debugging) and the other requires you to set up a "run configuration", and is basically identical to the Netbeans or Eclipse setup. With both **you must first change the IDE "Debug port" in "Preferences" to 11011.**

![Setting the listen port](images/phpstorm_debug_port.png)
[PHPStorm](https://www.jetbrains.com/phpstorm/download) is a leading PHP development IDE with extensive built-in debugging support. It provides two different ways to do debugging. One requires very little effort in the PHPStorm IDE (they call it zero-configuration debugging) and the other requires you to set up a "run configuration", and is basically identical to the Netbeans or Eclipse setup.

#### PHPStorm Zero-Configuration Debugging

PHPStorm [zero-configuration debugging](https://confluence.jetbrains.com/display/PhpStorm/Zero-configuration+Web+Application+Debugging+with+Xdebug+and+PhpStorm) means you only have to:

1. Make sure your "Debug port" is set to 11011 in preferences.
2. Toggle the “Start Listening for PHP Debug Connections” button:
1. Toggle the “Start Listening for PHP Debug Connections” button:
![Start listening for debug connections button](images/phpstorm_listen_for_debug_connections.png)
3. Set a breakpoint.
4. Using bookmarks from https://www.jetbrains.com/phpstorm/marklets/, "start debugger"
5. Visit a page that should stop in the breakpoint you set.
2. Set a breakpoint.
3. Visit a page that should stop in the breakpoint you set.

#### PHPStorm "Run/Debug configuration" Debugging

PHPStorm [run/debug configurations](https://www.jetbrains.com/help/phpstorm/2017.1/run-debug-configurations.html) require slightly more up-front work but can offer more flexibility and may be easier for some people.
PHPStorm [run/debug configurations](https://www.jetbrains.com/help/phpstorm/creating-and-editing-run-debug-configurations.html) require slightly more up-front work but can offer more flexibility and may be easier for some people.

1. Make sure your "Debug port" is set to 11011 in preferences.
2. Under the "Run" menu select "Edit configurations"
3. Click the "+" in the upper left and choose "PHP Web Application" to create a configuration. Give it a reasonable name.
4. Create a "server" for the project. (Screenshot below)
5. Add file mappings for the docroot of the server. If your repo has the main code in the root of the repo, that will map to /var/www/html. If it's in a docroot directory, it would map to /var/www/html/docroot.
6. Set an appropriate breakpoint.
7. Start debugging by clicking the "debug" button, which will launch a page in your browser.
1. Under the "Run" menu select "Edit configurations"
2. Click the "+" in the upper left and choose "PHP Web Application" to create a configuration. Give it a reasonable name.
3. Create a "server" for the project. (Screenshot below)
4. Add file mappings for the files on the server. Click on the local repo path and add "/var/www/html" as the "Absolute path on the server" and your repository root as the path on the host.
5. Set an appropriate breakpoint.
6. Start debugging by clicking the "debug" button, which will launch a page in your browser.

![PHPStorm debug start](images/phpstorm_config_debug_button.png)

Expand All @@ -70,50 +63,47 @@ Server creation:

![PHPStorm server creation](images/phpstorm_config_server_config.png)

<a name="netbeans"></a>
### Netbeans Debugging Setup

[Netbeans](https://netbeans.org/) is a free IDE which has out-of-the-box debugging configurations for PHP. You'll want the *PHP* download bundle from the [download page](https://netbeans.org/downloads/).

Before, beginning anything else, please set your Debugger Port to 11011. (Preferences->PHP->Debugging):

![Netbeans Debugging Port](images/netbeans_debugger_port.png)

1. Create a PHP project that relates to your project repository. (File->New Project->PHP Application with Existing Sources)
2. Under "Run as", choose "Local web site (running on local web server)".
3. Under "Name and Location", give the sources folder of the **docroot/webroot** of your project.
![Netbeans project name and location](images/netbeans_project_name_location.png)
4. Under "Run configuration" the project URL to the full URL of your dev project, for example http://drud-d8.ddev.local/, and choose the index file.
![Netbeans run configuration](images/netbeans_project_run_configuration.png)
5. Set a breakpoint.
6. Click the "Debug" button.

<a name="atom"></a>
### Atom Debugging Setup

[Atom](https://atom.io/) is an extensible developers' editor promoted by GitHub. The available extensions include [php-debug](https://atom.io/packages/php-debug) which you can use to conduct PHP debugging with the Xdebug PHP extension. This project is currently an alpha release.

1. Install an xdebug helper extension for your browser, [as suggested in documentation](https://atom.io/packages/php-debug#setting-up-xdebug)
2. Under Preferences->+Install install the php-debug add-on:
1. Under Preferences->+Install install the php-debug add-on:
![php-debug installation](images/atom_php_debug_install.png)
3. Add configuration to the Atom config.cson by choosing "Config..." under the "Atom" menu. A "php-debug" stanza must be added, with file mappings that relate to your project. (Example [config.cson snippet](snippets/atom_config_cson_snippet.txt)
2. Add configuration to the Atom config.cson by choosing "Config..." under the "Atom" menu. A "php-debug" stanza must be added, with file mappings that relate to your project. (Example [config.cson snippet](snippets/atom_config_cson_snippet.txt)
![Atom cson config](images/atom_cson_config.png)
4. Open a project/folder and open a PHP file you'd like to debug.
5. Set a breakpoint. (Right-click->PHP Debug->Toggle breakpoint)
6. Turn on debugging in Atom (Right-click->PHP Debug->Toggle Debugging)
7. Turn on debugging in your browser using the browser extension.
8. Visit a page that should trigger your breakpoint.
3. Open a project/folder and open a PHP file you'd like to debug.
4. Set a breakpoint. (Right-click->PHP Debug->Toggle breakpoint)
5. Open the debug view and enable debugging by choosing Packages->PHP-Debug->Toggle Debugging. You should see "Listening on address:port 127.0.0.1:9000".
6. Visit a page that should trigger your breakpoint.

An example configuration from [user contribution](https://github.com/drud/ddev/issues/610#issuecomment-359244922):
An example configuration:
```
"php-debug":
AutoExpandLocals: true
DebugXDebugMessages: true
MaxDepth: 6
"php-debug":
PathMaps: [
"/path/to/container/docroot;/path/to/host/docroot"
"remotepath;localpath"
"/var/www/html;/Users/rfay/workspace/d8git"
]
PhpException: {}
ServerAddress: "172.28.99.99"
ServerPort: 11011
```

<a name="vscode"></a>
### Visual Studio Code (vscode) Debugging Setup

1. Install the [php-debug](https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-debug) extension.
2. Add to the launch.json the stanza defining "Listen for xdebug" (see [config snippet](snippets/vscode_listen_for_xdebug_snippet.txt))
3. Set a breakpoint in your index.php. If it isn't solid red, restart.
4. Click the vscode debug button: ![vscode debug button](images/vscode_debug_button.png).
5. Run the "Listen for XDebug" job: ![Listen for XDebug](images/vscode_run_listen_xdebug.png)
6. Go to a page in your project, you should hit your breakpoint.

## Using xdebug on a Port Other than the Default

By default, ddev is set up to contact the default port, port 9000 on your IDE. However, if you have something else listening on that port, you'll need to change the port. (The most likely conflict is php-fpm, which also has 9000 as a default port.)

* To override the port, add an override file in the project's .ddev/php directory. For example, a file .ddev/php/xdebug_remote_port.ini:

```
[PHP]
xdebug.remote_port=11011
```
* Then change your IDE's configuration to listen on the new port.
3 changes: 3 additions & 0 deletions pkg/ddevapp/ddevapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ type DdevApp struct {
DBAImage string `yaml:"dbaimage"`
RouterHTTPPort string `yaml:"router_http_port"`
RouterHTTPSPort string `yaml:"router_https_port"`
XdebugEnabled bool `yaml:"xdebug_enabled"`
AdditionalHostnames []string `yaml:"additional_hostnames"`
ConfigPath string `yaml:"-"`
AppRoot string `yaml:"-"`
Expand Down Expand Up @@ -166,6 +167,7 @@ func (app *DdevApp) Describe() (map[string]interface{}, error) {
appDesc["php_version"] = app.GetPhpVersion()
appDesc["router_http_port"] = app.RouterHTTPPort
appDesc["router_https_port"] = app.RouterHTTPSPort
appDesc["xdebug_enabled"] = app.XdebugEnabled

return appDesc, nil
}
Expand Down Expand Up @@ -736,6 +738,7 @@ func (app *DdevApp) DockerEnv() {
"DDEV_PROJECT_TYPE": app.Type,
"DDEV_ROUTER_HTTP_PORT": app.RouterHTTPPort,
"DDEV_ROUTER_HTTPS_PORT": app.RouterHTTPSPort,
"DDEV_XDEBUG_ENABLED": strconv.FormatBool(app.XdebugEnabled),
}

// Find out terminal dimensions
Expand Down
43 changes: 43 additions & 0 deletions pkg/ddevapp/ddevapp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,49 @@ func TestDdevStartMultipleHostnames(t *testing.T) {
}
}

// TestDdevXdebugEnabled tests running with xdebug_enabled = true, etc.
func TestDdevXdebugEnabled(t *testing.T) {
assert := asrt.New(t)
app := &ddevapp.DdevApp{}

site := TestSites[0]
runTime := testcommon.TimeTrack(time.Now(), fmt.Sprintf("%s DdevXdebugEnabled", site.Name))

err := app.Init(site.Dir)
assert.NoError(err)

// Run with xdebug_enabled: false
testcommon.ClearDockerEnv()
app.XdebugEnabled = false
err = app.WriteConfig()
assert.NoError(err)
err = app.Start()
assert.NoError(err)

stdout, _, err := app.Exec("web", "php", "--ri", "xdebug")
assert.Error(err)
assert.Contains(stdout, "Extension 'xdebug' not present")

// Run with xdebug_enabled: true
//err = app.Stop()
testcommon.ClearDockerEnv()
app.XdebugEnabled = true
err = app.WriteConfig()
assert.NoError(err)
err = app.Start()
assert.NoError(err)
stdout, _, err = app.Exec("web", "php", "--ri", "xdebug")
assert.NoError(err)
assert.Contains(stdout, "xdebug support => enabled")
assert.Contains(stdout, "xdebug.remote_host => host.docker.internal => host.docker.internal")

err = app.Stop()
assert.NoError(err)

runTime()

}

// TestStartWithoutDdev makes sure we don't have a regression where lack of .ddev
// causes a panic.
func TestStartWithoutDdevConfig(t *testing.T) {
Expand Down
1 change: 1 addition & 0 deletions pkg/ddevapp/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ services:
- DDEV_PROJECT_TYPE=$DDEV_PROJECT_TYPE
- DDEV_ROUTER_HTTP_PORT=$DDEV_ROUTER_HTTP_PORT
- DDEV_ROUTER_HTTPS_PORT=$DDEV_ROUTER_HTTPS_PORT
- DDEV_XDEBUG_ENABLED=$DDEV_XDEBUG_ENABLED
- DEPLOY_NAME=local
- VIRTUAL_HOST=$DDEV_HOSTNAME
- COLUMNS=$COLUMNS
Expand Down
1 change: 1 addition & 0 deletions pkg/testcommon/testcommon.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ func ClearDockerEnv() {
"DDEV_ROUTER_HTTPS_PORT",
"COLUMNS",
"LINES",
"DDEV_XDEBUG_ENABLED",
}
for _, env := range envVars {
err := os.Unsetenv(env)
Expand Down
2 changes: 1 addition & 1 deletion pkg/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var DockerComposeVersionConstraint = ">= 1.10.0-alpha1"
var WebImg = "drud/nginx-php-fpm-local" // Note that this is overridden by make

// WebTag defines the default web image tag for drud dev
var WebTag = "v1.2.2" // Note that this is overridden by make
var WebTag = "v1.3.0" // Note that this is overridden by make

// DBImg defines the default db image used for applications.
var DBImg = "drud/mariadb-local" // Note that this is overridden by make
Expand Down

0 comments on commit 38209b6

Please sign in to comment.