legacy-cli
legacy-cli copied to clipboard
Support opening an SSH tunnel to XDebug
I'd like to have the ability to map custom ports (in my case, for XDEBUG).
So, something like platform tunnel:open 9000
which would then map to a port based on the clients current port mapping logic (i.e. 30009).
I'm happy to contribute to this, however, what is the preferred method?
- Adding a custom mapping argument?
- Or, since tunnel currently cycles through relationships being able to add XDEBUG as a relationship/service?
[Just adding context for now, I'll think about how best to support this]
For new tunnels, currently, the port is selected as the next available port number, starting from 30000.
https://github.com/platformsh/platformsh-cli/blob/9c12360f5dba1470a2b943bc7267a6fb1fe08263/src/Command/Tunnel/TunnelOpenCommand.php#L78 https://github.com/platformsh/platformsh-cli/blob/9c12360f5dba1470a2b943bc7267a6fb1fe08263/src/Command/Tunnel/TunnelCommandBase.php#L151-L159 https://github.com/platformsh/platformsh-cli/blob/9c12360f5dba1470a2b943bc7267a6fb1fe08263/src/Util/PortUtil.php#L84-L93
Since this can be so wide open and there are so many variations in how ports may become available, making this a poor choice for relationships, maybe the appropriate flow is: platform tunnel:open --app=[application] --app-port=[application port]
If my application is called "Laravel" and I want a tunnel to port 9000: platform tunnel:open --app=laravel --port=9000
.
If the next available port is 30005, then we now have: 127.0.0.1:30005 => laravel:9000
Edit I'm sure "environment" is more appropriate than "application".
For development purposes, it might be a good option to have a "--match" flag that would force the ports to match. So, in this case 9000 would map to 9000.
The command opens tunnels for 1 application (inside 1 environment). Each application can have multiple relationships (to services, e.g. mysql + redis), and the command opens tunnels for all of those relationships. Each of those tunnels needs a local port number.
But we might need to go back a step here. You can't control what the remote port number would be: you can't have an application listening on port 9000 at the moment (unless there's something I've missed). Some kind of remote Xdebug service would be nice, but I think if we offered it, it would be something we'd implement with a simplified API.
Xdebug is a PHP extension which, by default, uses port 9000. Xdebug is supported by Platform.sh. We use it today. Currently, we communicate with it by using SSH to tunnel to the application at 9000.
Oops, I didn't realise we did that yet. That will need a special case implementation in the CLI, as far as I can see.
Some notes: XDebug doesn't run on port 9000 in the app. Xdebug connects to by default localhost:9000
, which is the opposite direction of the tunnel:open
command.
tunnel:open
uses i.e. ssh -L 30000:database.internal:3306
and opens a local tunnel (creates a listening port on your machine), so you can connect on the local port 30000
, which is forwarded to the apps relationships port database.internal:3306
.
For XDebug you need to use an remote tunnel with ssh -R 9000:localhost:9000
, which opens a remote tunnel in the app (creates a listening port in the app container), so xdebug can connect on port 9000 on the container to your IDE on port 9000.
Varying ports are not nice for xdebug, as you have to set the xdebug port in the IDE to listen to it.
@emiikhaos and I think devs expect this. That means from platform.sh's perspective, the cli only needs to use that port. If it can't open it, let the dev know it's already in use.
Still, tunnel:open
works in the opposite direction as xdebug needs. I wouldn't expect an inconsistent behavior when using the command. Especially I wouldn't expect to get warning when using it in two projects.
I would recommend two new commands like xdebug:start
and xdebug:stop
to establish the remote tunnel for port 9000. So it has its own consistency and you know you have to stop another one before starting to use it in the second project.