Skip to content

php debugging with xdebug on production server guide

Debugging php code on a production server using xdebug is a pain to get working.
This guide will help you set it up and make sure it works.

Server Operating System: Ubuntu 18.04.3 LTS, apache and php fpm
Client Operating System: Windows 10, PHPSTORM

# install xdebug on production server
apt install php-xdebug

# xdebug gets automatically activated for all 3 php clients
# disable xdebug for all php cli, apache2 and fpm
phpdismod xdebug

# edit xdebug config
nano /etc/php/7.2/mods-available/xdebug.ini


# remote debugger
xdebug.remote_port=9001 # use port 9001 as 9000 is used by php-fpm
xdebug.remote_log = "/var/log/xdebug/xdebug.log"

# make xdebug log directory
mkdir -p /var/log/xdebug

# and make it owned by www-data
chown www-data:www-data /var/log/xdebug

# enable xdebug for php fpm only
phpenmod -s fpm xdebug

# restart php
systemctl restart php7.2-fpm

# create test page to check if xdebug is working - check for xdebug section in phpinfo()
function test()
echo "Called @ ".xdebug_call_file() .":". xdebug_call_line() ." from". xdebug_call_function();

# install browser plugin

Chromium - first install it to chrome, then in chromium go to extensions, activate developer mode and load the extension from

C:\Users\USER\AppData\Local\Google\Chrome\User Data\Default\Extensions\eadndfjplgieldjbigjakmdgkmoaaaoc

# set browser plugin IDE key to PHPSTORM

# create SSH tunnel between the server and the local machine
The cool thing about the SSH tunnel between the server and the local machine is that it will work whatever firewall settings and network configuration.

ssh -i private-key.pem -R 9001:localhost:9001 -N -v

# setup PHPSTORM
* in run menu: start listening for debug connections + break on first line
* file > settings > PHP > Debug > XDebug > port 9001

# happy debugging!

# profile php code

# enable profiler globally
;xdebug.profiler_enable = 1

# enable profiler if trigger is used
xdebug.profiler_enable_trigger = 1
xdebug.profiler_enable_trigger_value = "hello"

;xdebug.profiler_append = 1
xdebug.profiler_output_dir = "/var/log/xdebug"
;xdebug.profiler_output_name = "callgrind.out.%t-%s"
xdebug.profiler_output_name = "cachegrind.out.%s.%H"

# start profiler