iakta.org
it
1 December 2017 | 6 min. ( 1105 words ) | by walter

How to debug PHP inside Docker from IntelliJ

How to debug PHP on our IDE when PHP is running on a Docker container (possibly on the same machine)
PHP Docker IntelliJ Debug

IntelliJ (and of course PHP Storm) are wonderful IDEs, and can help you debug your applications and your servers either locally or remotely.

Since a few releases, IntelliJ can also debug a server running inside a Docker container, possibily running on the same PC/Mac where the IDE is running. But, the nice part is, thanks to TCP/IP this was possible even before Docker integration. It’s just a matter of configuring debugging for a generic remote server..

In this example we’ll see how to debug PHP, but the same principles apply to many other languages.

** Configuring PHP inside Docker**
We assume you have an up and running PHP configuration inside Docker, possibly with an Nginx web server and another container for the DB. THis should be up and working prior to trying to configure debugging.

The first step is to ensure tha PHP (usually PHP-FPM) is configured to have debugging enabled. We will cover debugging using the XDebug extension.

To ckeck that PHP has Xdebug eanbled, you can
* log into the Docker container and do a php -i | grep xdebug
* create a .php file containing just <?php phpinfo(); and load it in a browser

Just check that you have the key xdebug support => enabled. If not you have to enable or compile PHP with XDebug.

It depends on the Dockerfile you are using, but usually it has two steps:
1. compiling Xdebug inside PHP directly
1. or adding it as an extension
1. AND enabling via some configuration options.

As to how to enable XDebug in PHP, it’s too Dockerfile-dependant. Many dockerfile for PHP can be configured to have XDebug enabled. Please see the relevant documentation.

Once XDebug is installed and enabled, you have to configure it. To configure it you must ensure that during the docker build phase, the correct settings for XDebug are copied to the container.

In our Docker-compose directories, there is a xdebug.ini file that gets copied.
Please see it has the following keys:

xdebug.remote_autostart=1
xdebug.remote_enable=1
xdebug.remote_port=<DEBUG_SERVER_PORT>
xdebug.remote_host=<DEBUG_SERVER_HOST>

This will tell the XDebug module to connect to a debug server on the given host and port. The server will be our beloved IDE IntelliJ. Bear in mind, while debugging PHP remotely, the client is the PHP engine (PHP-FPM usually) while the server is our IDE.

Pick any random free port for your debug server port, i.e. 9999 and get the adress of our machine, as seen from a docker container.

The last point is very important. Evey Docker host can help you. For example on MacOSX (MacOS now) latest releases of Docker have the special docker.for.mac.host.internal name that always point to the host Mac.

So in our case the configuration looks like:

xdebug.remote_autostart=1
xdebug.remote_enable=1
xdebug.remote_port=9999
xdebug.remote_host=docker.for.mac.host.internal

If you put numeric addresses, please check them from inside the PHP docker container, by pinging the address. If ping is unavailable, just add this to your Dockerfile a few lines befor the end: RUN apt-get update -yqq && apt-get -y install telnet iputils-ping, or run the command once inside the container.

If you want, you can set these other two keys:

xdebug.idekey=<AN_IDE_JEY>
xdebug.remote_log=<A_LOG_FILE>

THe first one helps you debug directly without having to start the debugging from the IDE (or debugging PHP not from a web browser, i.e. from a call to PHP originating from mobile app or a IoT device), the second one can help you troubleshoot why the debugging does not start.
Most of the times it’s because the xdebug.remote_host is wrong.

We hade one case using a well-konwn package for Docker/PHP named Vessel where Vessel itself overwrote our configuration of the remote host with one it thought it was more correct. In fact it wasn’t. JUst modifying the Vessel script took care of the problem.

So to summarize, our full xdebug.ini file looks like that:

xdebug.remote_autostart=1
xdebug.remote_enable=1
xdebug.remote_port=9999
xdebug.remote_host=docker.for.mac.host.internal
xdebug.idekey=INTELLIJ
xdebug.remote_log=/var/log/xdebug.log

As usual, do a docker build of the container, and check when the container is running, that the configuration are correct.

** Configuring IntelliJ/PHPStorm **

This is the tricky part, and involves a few steps:
1. confugure XDebug
1. define a server entry for our docker container
1. define a Run/Debug configuration
1. start debugging

The trickiest part is the 1st, in my opinion.
So..

First we configure XDebug.
Go to the Preferences menu and look for Languages & Frameworks | PHP | Debug. In the XDebug section set:

  • the Debug port to the one in the xdebug.ini file. In our example it’s 9999.
  • Check just Can accept external connections and do not, unless you really need it, check the two Force break on.. otpions.

This option tells IntelliJ that debugging can also start from the client. It is the only way to debug command line scripts or non web clients, as mobile apps.

Then go to the same Preferences menu and look for Languages & Frameworks | PHP | Servers.
Add a new server, give it a name (the name is important), and configure it

title

  • The Host and Port is used when launching the debugger from IntelliJ. If you plan to use this feature, set them correctly, otherwise set them to anything.
  • Choose XDebug
  • Check Use path mapping and define at least one mapping between the source code on you Mac/PC file system, and the path on the Docker container.
  • Since we use Laravel, we have set up also the path to the public directory explicitly. In Laravel, this is the directory where the index.php file resides. And the directory that is set as root path in nginx config.

Then click Apply and quit the dialog.

Next we need to configure debugging.

Click the Run menu and choose Edit configurations....
Add (the [+] icon on the top right) a new PHP web page and configure it

give it a name. It’s not important.
* Choose the Server you have set up before.
* Choose a starting URL (it can be anything on your server) and a prefereed browser.

Click OK and save.

Now to test it, on the top toolbar of INtelliJ, near the top right, select the configuration just created.

title

Then start debugging by pressing the green bug button. This will launch a browser with the url you have set up: http://rotor.local:9980/it?XDEBUG_SESSION_START=11227

Notice the XDEBUG_SESSION_START. If you inspect the cookies of your browser you will see that it has setup a cookie names XDEBUG_SESSION. This is the key to remote debuggig.
IntelliJ will bring up a Debug panel, and in the variable pane it will tell Waiting for incoming connection with ide key '13326'.

From now on breakpoints works as expected.

See our other article on how to debug without starting from a browser.

PHP Docker IntelliJ Debug
Twitter Facebook Google+

Debug PHP calls issued from Command Line or mobile Apps

…

Surviving the WWDC

…

Privacy Policy © 2017 Iakta srl Published with Hugo and Cockpit CMS using Hugocockpit Theme based on Bleak by zutrinken
Menu