FROM php:7.0-apache RUN a2enmod rewrite RUN docker-php-ext-install pdo pdomysql RUN yes pecl install xdebug && echo 'zendextension=$ (find /usr/local/lib/php/extensions/ -name xdebug.so)' /usr/local/etc/php/conf.d/xdebug.ini && echo 'xdebug.remoteenable=on' /usr/local/etc/php/conf.d/xdebug.ini && echo 'xdebug.remoteautostart=off'. Instruct XDebug to connect to host.docker.internal for command line execution or whenever “connect back” is not possible. Set PHPIDECONFIG env variable to serverName=localhost. This will tell your PhpStorm which server configuration to use. See next step for details.
On this post we are setting up a Docker Container for Centos 7 and PHP 7.3 with an installation of Xdebug.
If you compare this Dockerfile with our previous one for PHP 7.3 you will notice that we have included the php-devel package. This is required since we will be using pecl to install Xdebug, which will build, install and load it.
Additionally we will need to install the make package.
Additionally we will need to install the make package.
You can also download this Dockerfile here
The Dockerfile also updates the /etc/php.ini file, by adding the following xdebug section:
- Note that we have specified host.docker.internal as the IP address of our host machine, instead of an actual IP address. That is a docker variable that will be translated into the IP address of the machine running the docker container.
Create the Docker Image and Container
Now we create the Docker Image.
Then we create the Docker Container.
Notice that we need to indicate the path of our local folder that will be served as the root of the Apache Web Server, which in this example is /path_to/my_website. Replace it with the location of your site's root folder.
After the Docker Container is created, you can go to the url http://localhost:4000 to open the local website.
To check Xdebug has been correctly installed and configured, open a terminal window into the Docker Container with the following command:
Then, on the terminal window inside the container, we will use the php -i instruction to get information about our PHP installation. We will also use the grep utility to display only the information relevant to Xdebug:
You will see an output similar to this one (excerpts):
Downloads
Check the Dockerfile on Github here.
Download the Image from Docker Hub here.
Debugging is an important aspect of any test environment. It helps developer troubleshoot their code on a deployed environment.
XDebug is one of the popular debuggers for PHP and many PHP IDEs have built-in support for XDebug.
Docker provides official images for
php-fpm
and nginx
. php-fpm
process all the PHP code and for client request handling we will use nginx.In this article we will explore 2 approaches for using XDebug in a php-fpm + Nginx setup. Before we dive into these approaches, we first need to see how to setup a simple version
Setting up Nginx and PHP-FPM
We first write a
docker-compose.yml
fileThe
php_testapp
folder has a simple index.php
php_testapp/index.php
app.conf
We get the environment up and running using
docker-compose up -d
and then browse to http://<dockerhost>:8080/
to test our setup. If all works well you will see a PHP Info pageNow let us look at both the approaches one by one
Approach 1 - Using Fixed IP
First we need to install XDebug into the
php-fpm
image as it doesn’t come as a part of the official imageDockerfile
We add
99-xdebug.ini
which contains settings for XDebug99-xdebug.ini
Note: The official port for XDebug is
9000
, but since we are running php-fpm
which also runs on 9000 port, I prefer running XDebug on 9009
Now we update our
app.conf
to update some of the XDebug settings through fastcgi_param
app.conf
We would also update our
docker-compose.yml
to build our Dockerfile
instead of using the official image192.168.0.104
in this case is my machine’s IP. This IP needs to be reachable from the main docker host machineWe have enabled
remote_autostart
and remote_enable
through Nginx config instead in our docker image using 99-xdebug.ini
. Doing so gives us better control over switching XDebug on and off.Since we may debug from different network setup (home, office), the IP would need to be changed according to the network. This would require a reload or restart of the nginx server using
docker-compose restart nginx
This approach is very simplistic, doesn’t have much overhead, except updating IP.
Docker Xdebug Phpstorm Windows
Approach 2 - Using SSH and Reverese Tunneling
In this approach we first setup ssh in the
php-fpm
image. Since we will be running sshd
and php-fpm
both, we would run them using Supervisor![Windows Windows](https://raw.githubusercontent.com/gist/michelluca/f08a1e21aaaff4fce752993c86f08427/raw/ee36b9354dacbed8b8a46a428e87eb63964fac92/PhpStorm DBGP proxy Session.png)
First thing we do is update our
Dockerfile
to install ssh and set password for our root account. The code is inspired from herePhpstorm Docker Xdebug Not Working
Dockerfile
Note: It is possible to use key based authentication instead of password based. I have left the code commented, if you are interested to do the same
To run
php-fpm
and sshd
we also create a supervisor_app.conf
supervisor_app.conf
docker-compose.yml
We make a small change in our
docker-compose.yml
to map 22
portWe also update our nginx
app.conf
file and change the xdebug.remote_host
to localhost
app.conf
Now that we have everything set, we just need to run the composition again using
docker-compose up -d
.The reason we set
xdebug.remote_host
as localhost is that we would use SSH reverse tunnel to map any traffic on port 9009
of our docker container to reach our machine directly.To create a reverse ssh tunnel, run the below command
Debug Php Vscode Remote
Note: The password in our case is
mypassword
Docker Php Xdebug Slow
Once the tunnel is open, if you configure your IDE to listen on port
9009
and open the url http://<dockerhostip>:8080/
on your machine, the debugger should pause on index.php
code as shown belowNote: This is not a recommended approach for production deployments. You don’t want to allow SSH inside containers in a prod environment.Anyways if you are debugging on production, then it really doesn’t make much sense. But sometimes that may be the need of hour, in that case use Approach 1.This approach is best suited where multiple developers would be debugging the code and changing IP everytime might be a pain
You can download the code for this article from tarunlalwani/php-xdebug-docker