Debugging PHP

Reverse Port Forwarding for PHP

We have an application using the de-facto standard for PHP, XDebug and an IDE from the Jetbrains suite, but the process is similar for other debugging tools and IDEs.

XDebug is a debugger that initiates the connection towards your IDE, so a reverse port forwarding is required, unlike many debuggers which accep connections from the IDE.

The default debugger port is9003 for XDebug 3 and we have not changed it, but if you have configured it to something else, don't forget to replace it in all steps below.

🚧

Pre-requisites

You will need a container image with XDebug installed in order to allow debugging PHP in a container.

For the example below we used the PHP application from our examples repository: https://github.com/bunnyshell/env-yaml-examples/tree/master/apps/php


Prepare the container image

First, create the config file for XDebug, in a folder named .docker:

zend_extension=xdebug

xdebug.discover_client_host=false
xdebug.client_host=127.0.0.1
xdebug.client_port=9003
xdebug.mode=develop,debug,trace
xdebug.start_with_request=yes
xdebug.idekey=PHPSTORM

In the Dockerfile for your PHP application, install the XDebug extension.

RUN install-php-extensions xdebug-3.1.5

Then, copy the

COPY .docker/docker-php-ext-xdebug.ini /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini

We used php:8.0.25-fpm-alpine as the base image.


Starting Remote Development

Step 1. Start remote development in Bunnyshell

You can start remote development and determine the Component using the built-in wizard, or you can specify it directly. Please see the start documentation for more details.

Since you need a reverse port forwarding for the 9003 port, in Bunnyshell CLI you would write the port forward as 9003<9003. Basically, you would need to run something similar to the command below, but replacing the Component ID with your own:

$ bns remote-development up --component RZmMRQX0kV --port-forward "9003<9003"

The local path (the one on your machine) will be requested, as the source of the code sync. It is automatically pre-filled with the current folder.

$ bns remote-development up --component RZmMRQX0kV --port-forward "9003<9003"
? Local Path [tab for suggestions] (/Users/myuser/playground/env-yaml-examples/apps/php)

Then, you will need to provide the path within the container, which represents the target for the code sync.

$ bns remote-development up --component RZmMRQX0kV --port-forward "9003<9003"
? Local Path /Users/myuser/playground/env-yaml-examples/apps/php
? Remote Path

After providing it, Bunnyshell starts to perform the Remote Development changes within your cluster: a PersistentVolumeClaim is attached to your Pod and the container's command is changed, so you can have an SSH terminal (or more) into the container and ports forwarded, as well as for the file sync to happen.

$ bns remote-development up --component RZmMRQX0kV --port-forward "9003<9003"
? Local Path /Users/myuser/playground/env-yaml-examples/apps/php
? Remote Path /var/www
\ Waiting for pod to be ready

You can provide the local path and remote path also via command parameters, --local-sync-path (or -l) and --remote-sync-path (or -r).

After the Pod definition is changed, you will be having access to the container itself through and SSH shell.

$ bns remote-development up --component RZmMRQX0kV --port-forward "9003<9003"
? Local Path /Users/myuser/playground/env-yaml-examples/apps/php
? Remote Path /var/www
/var/www #

Once you're in, you need to start the php-fpm process.

$ bns remote-development up --component RZmMRQX0kV --port-forward "9003<9003"
? Local Path /Users/myuser/playground/env-yaml-examples/apps/php
? Remote Path /var/www
/var/www # php-fpm

You will see the output of the command, which will confirm that the process is running.

$ bns remote-development up --component RZmMRQX0kV --port-forward "9003<9003"
? Local Path /Users/myuser/playground/env-yaml-examples/apps/php
? Remote Path /var/www
/var/www $ php-fpm
[23-Nov-2022 09:57:05] NOTICE: [pool www] 'user' directive is ignored when FPM is not running as root
[23-Nov-2022 09:57:05] NOTICE: [pool www] 'group' directive is ignored when FPM is not running as root
[23-Nov-2022 09:57:05] NOTICE: fpm is running, pid 72
[23-Nov-2022 09:57:05] NOTICE: ready to handle connections
...

Setting up the IDE

From PhpStorm, you just need to start listening for debugging connections. For this to happen, click Start Listening for PHP Debug Connections from the toolbar, aka turn on the phone icon.

When you perform the first request on the remote application, Xdebug will start there and open a connection on 127.0.0.1 on port 9003 within the container, because you configured it this way in the ini file. Port 9003 from the container is mapped to port 9003 on your local machine, because you ran the bns remote-development up command with the --port-forward option, so the connection request from XDebug hits your local machine on port 9003, which will be picked up by PhpStorm.

A PHP Remote Debug configuration will be automatically created for you.

For projects in which the public folder is not the same as the project root folder, you will need to edit the configuration to add the folder mapping, from container to your local.

Open the Edit Configurations dialog.

Click the three dots next to the Server.

In the folder mapping area, enter the container folder next to the project's folder on your local machine.


Congratulations! You are now able to debug PHP applications remotely.