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:
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.
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.inifile. In our example it’s
- Check just
Can accept external connectionsand 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
Portis used when launching the debugger from IntelliJ. If you plan to use this feature, set them correctly, otherwise set them to anything.
Use path mappingand 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
publicdirectory explicitly. In Laravel, this is the directory where the
index.phpfile resides. And the directory that is set as root path in
Then click Apply and quit the dialog.
Next we need to configure debugging.
Run menu and choose
[+] 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.
Then start debugging by pressing the green bug button. This will launch a browser with the url you have set up:
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.