Question:
There are many posts on SO and elsewhere on how to set this up. So far I’ve been unsuccessful in getting it working.
Setup
Local machine – Windows 10, with Cygwin, git bash, and WSL2 with Ubuntu installed; and MacBook Air (Mojave)
Host machine – AWS EC2 instance running Amazon Linux 2
Docker container – CentOS 7.8 running PHP with Xdebug
Goal
Remotely debug PHP code in container from local machine by utilizing a reverse tunnel from the local machine to the container.
I have gotten this working before when the PHP code was installed locally on the host machine, so the question is not around Xdebug. As soon as I moved the PHP code into the container, debugging no longer works.
What I’ve tried
Setting up a reverse tunnel from the local machine to the host EC2 instance works. For this I’m doing ssh -vvv -i "aws.pem" -R 9000:localhost:9000 user@ec2instance
in terminal, cygwin, or git bash and testing with nc -z localhost 9000 || echo 'no tunnel open'
on the host machine.
When I docker exec -it container bash
into the container and run nc, the tunnel is not available.
I’m using docker-compose:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
version: '2' services: web: image: 'privateregistry/project/container:latest' restart: always container_name: web ports: - '8082:80' - '447:443' - '9000:9000' volumes: - '.:/var/www/project' |
I have tried with and without mapping the 9000 port. I have tried variations of the ssh tunnel:
ssh -vvv -i "aws.pem" -R :9000:localhost:9000 user@ec2instance
ssh -vvv -i "aws.pem" -R 0.0.0.0:9000:localhost:9000 user@ec2instance
ssh -vvv -i "aws.pem" -R \*:9000:localhost:9000 user@ec2instance
ssh -vvv -i "aws.pem" -R 9000:172.20.0.2:9000 user@ec2instance
(container IP)
I’ve also tried using ssh -L
with no luck.
Several posts, like this one suggest adding GatewayPorts yes
on the host machine. I’ve tried this as well with no change.
I have not tried using --network=host
, primarily due to security concerns. I also would rather not use ngrok, as I’d like to be able to use localhost or host.docker.internal
for the xdebug.remote_host
setting.
For completeness, here is what I have for Xdebug:
1 2 3 4 5 6 7 8 9 10 |
[XDebug] xdebug.remote_enable=1 xdebug.remote_autostart=1 xdebug.remote_handler="dbgp" xdebug.remote_port=9000 xdebug.remote_host="host.docker.internal" ;xdebug.remote_connect_back=1 xdebug.idekey = VSCODE xdebug.remote_log = "/var/log/xdebug.log" |
Answer:
I got this working. After reading up on the ssh man page and looking over things again, I realized I was binding to the docker container IP not the bridge (docker0) IP.
I updated my connect command to ssh -vvv -i "aws.pem" -R 9000:172.17.0.1:9000 user@ec2instance
with the right IP and the tunnel started working. I do still have GatewayPorts enabled (per the man page) and removed the 9000:9000 mapping.
I then updated my xdebug.remote_host value to the same IP and debugging is now working. Not sure why host.docker.internal didn’t work, but that’s for another day.