One e-commerce site had a very strange issue, it stop working as expected after cache cleaning. This issue appeared only on production server and couldn’t be reproduced on local machine. So there wasn’t another solution how debug problem directly on the server.
It’s really important to closely check all configuration because one little mistake and you will spend hours or days to find out a problem. I spent 2 days, before I clarified that port on the server had been used by another process.
This tutorial will explain steps by steps how to debug PHP codes on remote Ubuntu 64-bit Server with PHP-FPM (FastCGI Process Manager), PHP 7.2 and Nginx.
Remote Server’s steps
Install xDebug
sudo apt install php-xdebug
Check port availability
xDebug will need a port (usually its port 9000). To make sure the port that we will use for xDebug is available, lets check which ports are in use:
lsof -i:9000
It will display something like this:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
php-fpm7. 15224 root 12u IPv4 7878655 0t0 TCP localhost.localdomain:9000 (LISTEN)
Since port 9000 is already used (by PHP-FPM pool), we will use port 9005 for our xDebug.
Configure xDebug:
sudo vi /etc/php/7.2/mods-available/xdebug.ini
Add the following code into it:
; Enable xdebug extension module
zend_extension=xdebug.so
xdebug.idekey = PHPSTORM
xdebug.default_enable=1
xdebug.remote_autostart = 0
xdebug.remote_enable = 1
xdebug.remote_handler = dbgp
xdebug.remote_host = 127.0.0.1
xdebug.remote_log = /tmp/xdebug_remote.log
xdebug.remote_mode = req
xdebug.remote_port = 9005 # if you want to change the port you can change
Configure PHP_IDE_CONFIG
through Nginx
Open configuration file of your site and add next line:
location / {
...
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
fastcgi_param SCRIPT_NAME /index.php;
# this line is important if want to use custom configuration name instead of site domain
fastcgi_param PHP_IDE_CONFIG "serverName=print-machine";
...
}
We will use this value serverName=print-machine
when will configure PHPStorm.
NOTE: This step can be omitted, but in that case PHPStorm will automatically create configuration on first request, you’ll need just press "Apply" in popup window.
Restart the services:
sudo systemctl restart php-fpm
sudo systemctl restart nginx
Enable SSH Port Forwarding
Make sure that Allow TCP forwarding is enabled in your SSH server settings:
vi /etc/ssh/sshd_config
Look for:
AllowTcpForwarding yes
Restart the SSH service:
sudo systemctl restart sshd
Local Machine’s steps
Setup PHPStorm
Click "File" > "Settings…" > "Languages & Frameworks" > "PHP" > "Debug". Under "Xdebug" change the "Debug port" to your desired port. In out case we leave it default 9000.
Click Servers next to Debug and create new Server configuration.
Name and Host must be the same as we write in Nginx configuration PHP_IDE_CONFIG "serverName=print-machine"
. Don’t forget enable file mapping: left side – path to local project, right side – path to code on the server.
Create PHP Remote Debug
Click "Run" > "Edit configuration…", create new PHP Remote Debug
. In Server select server which we created previously, IDE key (session id) should be PHPSTORM:
Port forwarding
We will use SSH tunnel port forwarding for connecting to xDebug from PHPStorm.
Execute the following command in terminal:
ssh -R 9005:localhost:9000 <remote_user>@<remote_server_ip>
Where:
-R
9005:127.0.0.1:9000 opens up port 9005 as we set the server’s xDebug’sxdebug.remote_port
to 9005 earlier, then forwarded to localhost:9000 where PHPStorm is listening<remote_user>@<remote_server_ip>
are the username and hostname of the server
Nothing special you won’t see, it’ll open new session, connect to remote server and do port forwarding. Vualia!
Now, to test if the SSH tunnel port forwarding works, run the following command inside your SSH prompt on remove server:
lsof -i:9005
You should see something like this as response:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 30935 print-machine 9u IPv6 7824135 0t0 TCP ip6-localhost:9005 (LISTEN)
sshd 30935 print-machine 10u IPv4 7824136 0t0 TCP localhost.localdomain:9005 (LISTEN)
Run Debug
-
In your PhpStorm, click "Run" > "Break at first line in PHP scripts". This is optional, it is just to ensure that the PHPStorm will trigger when we started to debug our site. To start the PHPStorm listening to xDebug, click "Run" > "Start Listening for PHP Debug Connections".
-
Open your favorite web browser and visit your site. This should pop a window at PHPStorm that there’s incoming connection from xDebug, just click the "Accept" button.
-
Your PHPStorm will trigger to stop and highlight at the first line in your site’s PHP script.
Diving deeper
If still having problems you can use following tools in order to find the point where it fails:
tcpdump
showing xDebug activity
You can use tcpdump
command in order to verify if xDebug is even trying to connect to local machine — and if it does — which target it is trying to connect to.
sudo tcpdump -vv -nn -i any dst port 9000
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
23:50:31.531794 IP (tos 0x0, ttl 64, id 9877, offset 0, flags [DF], proto TCP (6), length 60)
127.0.0.1.45240 > 127.0.0.1.9000: Flags [S], cksum 0xfe30 (incorrect -> 0x6efe), seq 3410588541, win 65495, options [mss 65495,sackOK,TS val 3683447502 ecr 0,nop,wscale 7], length 0
This log shows that xDebug on the remote server (127.0.0.1) connects to my host machine (127.0.0.1) on port 9000. This information is very helpful to get a starting point for further debugging.
With the nc
command you can debug connectivity issues:
nc -w5 -z -v 127.0.0.1 9000
Connection to 127.0.0.1 9000 port [tcp/*] succeeded!
nc
connecting from within the remote server to the host machine at port 9000
With this we have verified that there is no connectivity issue due to wrong configuration or network restrictions.
Thank You !