多开发者通过SSH用VSCode+Xdebug调试单台LAMP服务器的方案
方案一:Xdebug discover_client_host + SSH-FS(无需VSCode Server)
适合服务器在本地局域网的场景,无需在服务器部署VSCode Server,可解决多客户端端口冲突,同时解决SSH-FS的路径映射问题。
配置步骤:
Linux服务器Xdebug配置
修改PHP配置文件(如/etc/php/8.1/mods-available/xdebug.ini),添加以下内容:xdebug.mode = debug xdebug.start_with_request = yes xdebug.discover_client_host = 1 xdebug.client_port = 9003重启PHP-FPM或Web服务器生效。
Windows客户端VSCode配置
通过SSH-FS挂载服务器代码目录后,在.vscode/launch.json中配置路径映射(核心是让VSCode关联本地挂载路径与服务器实际路径):{ "version": "0.2.0", "configurations": [ { "name": "Listen for Xdebug", "type": "php", "request": "launch", "port": 9003, "pathMappings": { "/var/www/project": "${workspaceFolder}" } } ] }其中
/var/www/project替换为服务器上的代码根路径,${workspaceFolder}对应本地SSH-FS挂载的目录。验证调试
每个开发者启动VSCode调试监听后,在浏览器触发调试请求(可通过Xdebug Helper插件开启调试),Xdebug会自动识别开发者的本地IP并回连,无需额外端口转发。
方案二:轻量调试代理(解决跨网络/端口冲突)
若服务器不在本地局域网,或discover_client_host无法正常工作,可使用轻量代理替代依赖繁重的php-xdebug-proxy,基于Python3实现,兼容当前版本。
配置步骤:
在Linux服务器部署代理
创建xdebug-proxy.py脚本:import socket import threading # 存储IDEkey与客户端连接的映射 client_map = {} def handle_xdebug_conn(proxy_sock): # 读取Xdebug请求中的IDEkey init_data = proxy_sock.recv(1024).decode() ide_key = None for line in init_data.split('\n'): if line.startswith('IDEkey:'): ide_key = line.split(':')[1].strip() break if not ide_key or ide_key not in client_map: proxy_sock.close() return # 转发数据到对应客户端 client_sock, _ = client_map[ide_key] client_sock.sendall(init_data.encode()) # 双向转发数据 def forward(src, dst): while True: data = src.recv(1024) if not data: break dst.sendall(data) threading.Thread(target=forward, args=(proxy_sock, client_sock)).start() threading.Thread(target=forward, args=(client_sock, proxy_sock)).start() def listen_xdebug(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(('0.0.0.0', 9003)) sock.listen(5) while True: conn, _ = sock.accept() threading.Thread(target=handle_xdebug_conn, args=(conn,)).start() def listen_clients(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(('0.0.0.0', 9004)) sock.listen(5) while True: conn, addr = sock.accept() ide_key = conn.recv(1024).decode().strip() client_map[ide_key] = (conn, addr) print(f"Registered client: {ide_key} from {addr}") if __name__ == "__main__": threading.Thread(target=listen_xdebug).start() threading.Thread(target=listen_clients).start() print("Xdebug proxy running on 0.0.0.0:9003 (Xdebug) and 0.0.0.0:9004 (clients)")运行代理:
python3 xdebug-proxy.py服务器Xdebug配置
修改Xdebug配置:xdebug.mode = debug xdebug.start_with_request = yes xdebug.client_host = 127.0.0.1 xdebug.client_port = 9003Windows客户端配置
- SSH连接时添加端口转发:
ssh -L 9004:localhost:9004 user@linux-server - 向代理注册IDEkey(每个开发者用唯一密钥,如
dev1):echo "dev1" | nc localhost 9004 - VSCode的
launch.json配置:{ "version": "0.2.0", "configurations": [ { "name": "Xdebug via Proxy", "type": "php", "request": "launch", "port": 9003, "ideKey": "dev1", "pathMappings": { "/var/www/project": "${workspaceFolder}" } } ] } - 浏览器中设置调试Cookie(如用Xdebug Helper插件选择
dev1作为IDEkey)。
- SSH连接时添加端口转发:
方案三:VSCode Remote SSH多端口隔离
若必须使用VSCode Remote SSH,可通过不同端口转发避免9003端口冲突。
配置步骤:
服务器Xdebug配置
保留discover_client_host开启:xdebug.mode = debug xdebug.start_with_request = yes xdebug.discover_client_host = 1客户端SSH配置
每个开发者在本地~/.ssh/config中配置独立的端口转发:Host linux-dev-dev1 HostName 192.168.1.100 User dev-user LocalForward 9003 localhost:9003 # 第二个开发者配置 Host linux-dev-dev2 HostName 192.168.1.100 User dev-user LocalForward 9004 localhost:9004VSCode调试配置
对应端口修改launch.json中的port字段,如第二个开发者设置"port": 9004,同时确保路径映射正确。
总结
- 优先选择方案一:本地局域网场景下最简洁,无需额外组件,解决SSH-FS路径映射问题即可正常调试。
- 跨网络场景选方案二:轻量代理避免依赖,通过唯一IDEkey区分多客户端。
- 依赖VSCode Remote SSH时选方案三:通过端口隔离解决冲突。
内容的提问来源于stack exchange,提问作者Mark Rogers

