Cursor 连接远程 Docker / Dev Container 失败问题总结

1. 问题现象

这次问题不是单纯的 SSH 连不上,而是 Cursor 在多层远程链路中某一层失败:

text 复制代码
Windows Cursor
  -> Remote SSH 连接远端宿主机 192.168.206.112 / 192.168.206.140
  -> Cursor Server 在远端宿主机启动
  -> Dev Containers 尝试 attach 到 Docker 容器 magatron / f3673e625a77
  -> 容器内 Cursor Server / extension host / WebSocket 连接失败

常见报错包括:

text 复制代码
Failed to connect to the remote extension host server
Error: WebSocket close with status code 1006
text 复制代码
Could not fetch remote environment
text 复制代码
Socket-mode code server reported /tmp/cursor-remote-ssh-;
expected /tmp/cursor-remote-ssh-xxxx/code.sock
text 复制代码
No remote exec server found for authority: dev-container...@ssh-remote...; using local
text 复制代码
Failed to read .gitconfig:
TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received undefined
text 复制代码
EADDRINUSE: address already in use 127.0.0.1:37265

2. 关键判断

2.1 SSH 层通常是成功的

日志里多次出现:

text 复制代码
SSH connection established

以及:

text 复制代码
Server install command exit code: 0

这说明 SSH 本身不是主要问题。

2.2 远端宿主机 Cursor Server 也能启动

日志里出现过:

text 复制代码
exitCode==0==
isFatalError==false==
codeListeningOn==/tmp/cursor-remote-ssh-.../code.sock==

说明远端宿主机上的 Cursor Server 能启动。

2.3 Docker 本身也基本正常

日志里出现:

text 复制代码
docker info: Command completed with exit code 0
docker inspect f3673e625a77: Command completed with exit code 0

说明 Docker 服务正常,容器也能被 inspect 到。

2.4 真正失败点在 Cursor Remote-Containers / Dev Containers 上下文

最关键的报错是:

text 复制代码
No remote exec server found for authority: dev-container...@ssh-remote...; using local

随后出现:

text 复制代码
Failed to read .gitconfig:
TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received undefined

这说明 Cursor 本来应该通过远端 SSH 上下文去 attach Docker 容器,但过程中 remote exec server 上下文丢失,导致 Cursor 退回到本地上下文,最终路径解析出错。


3. 主要原因汇总

原因 1:Cursor Remote-SSH 输出被 Windows 终端控制字符污染

日志中出现大量类似内容:

text 复制代码
Microsoft Windows [版本 ...]
C:\Users\...\cmd.EXE
\x1b[10;40H

同时 socket 路径被截断:

text 复制代码
Socket-mode code server reported /tmp/cursor-remote-ssh-;
expected /tmp/cursor-remote-ssh-xxxx/code.sock

说明 Cursor 在解析远端返回的 socket 路径时,被终端控制字符、换行或 cmd 输出污染。

解决方向:

  • 关闭 socket mode
  • 关闭登录终端显示
  • 使用干净的 SSH config
  • 避免 .bashrc 输出欢迎信息、echoclearconda activate 等内容

原因 2:Cursor / DevContainer 残留进程和 socket 文件冲突

日志中多次出现:

text 复制代码
Multiplex server script is already running
Code server script is already running
Server script is already running

这说明旧的 Cursor Server、multiplex server、forwarder、devcontainer-cli 进程仍在运行。它们可能持有旧 token、旧 socket 或旧端口,导致新连接失败。

解决方向:

  • 杀掉旧 Cursor 相关进程
  • 删除远端 /tmp/cursor-remote-ssh-*
  • 删除远端 /tmp/devcontainer-cli-*
  • 删除容器内 /root/.cursor-server

原因 3:Dev Container 端口转发冲突

日志里出现:

text 复制代码
EADDRINUSE: address already in use 127.0.0.1:37265

这说明某个本地或远端转发端口已经被占用。Cursor 会不断尝试新的 forwarder,但如果状态混乱,最终会导致 extension host 连接失败。

解决方向:

  • 关闭本地 Cursor
  • 杀掉本地 ssh.exe
  • 清理远端 forwarder.js / devcontainer-cli
  • 避免从旧的 Recent Project 直接恢复连接

原因 4:Cursor Dev Containers 缓存损坏或上下文丢失

关键报错:

text 复制代码
No remote exec server found for authority: dev-container...@ssh-remote...; using local

以及:

text 复制代码
The "path" argument must be of type string. Received undefined

这说明 Cursor 的 Remote Containers 状态损坏,或者从旧的 Recent Container 入口进入时没有正确拿到 SSH 上下文。

解决方向:

  • 清理本地 Cursor 的 anysphere.remote-containers 缓存
  • 不要直接点旧的 Recent Project
  • 先 Remote SSH 到宿主机,再 Attach Running Container

原因 5:.gitconfig / GPG / known_hosts 缺失引发干扰

日志里有:

text 复制代码
Failed to read /home/pcljgy/.ssh/known_hosts
text 复制代码
gpg: Fatal: can't open '/home/pcljgy/.gnupg/trustdb.gpg'

这些一般不是根因,但会增加连接过程中的异常分支。后面真正致命的是 .gitconfig path 为 undefined。

解决方向:

  • 在远端宿主机创建空的 known_hosts
  • 初始化 .gnupg
  • 关闭 Dev Containers 自动复制 Git 配置

原因 6:在 Docker 内执行 pkill -u "$USER"$USER 为空

Docker 内报过 pkill 使用帮助,原因通常是执行了:

bash 复制代码
pkill -u "$USER" -f cursor-server

但容器内 $USER 为空,实际变成:

bash 复制代码
pkill -u -f cursor-server

所以 pkill 报 usage。

解决方式:

容器内不要用 -u "$USER",改用:

bash 复制代码
pkill -f cursor-server || true

宿主机上可以用:

bash 复制代码
pkill -u "$(id -u)" -f cursor-server || true

4. 推荐的一次性修复流程

4.1 Windows 本地关闭 Cursor 和 SSH

在 Windows PowerShell 执行:

powershell 复制代码
taskkill /F /IM Cursor.exe
taskkill /F /IM ssh.exe

如果 ssh.exe 中有其他重要连接,不要直接杀所有 ssh.exe,可以用更精确的方式:

powershell 复制代码
Get-CimInstance Win32_Process |
  Where-Object { $_.Name -eq "ssh.exe" -and $_.CommandLine -like "*cursor-remote-ssh*" } |
  ForEach-Object { Stop-Process -Id $_.ProcessId -Force }

4.2 清理本地 Cursor Remote Containers 缓存

PowerShell 执行:

powershell 复制代码
Rename-Item "$env:APPDATA\Cursor\User\globalStorage\anysphere.remote-containers" `
  "$env:APPDATA\Cursor\User\globalStorage\anysphere.remote-containers.bak" `
  -ErrorAction SilentlyContinue

如果仍失败,再清理 Remote SSH 缓存:

powershell 复制代码
Rename-Item "$env:APPDATA\Cursor\User\globalStorage\anysphere.remote-ssh" `
  "$env:APPDATA\Cursor\User\globalStorage\anysphere.remote-ssh.bak" `
  -ErrorAction SilentlyContinue

4.3 配置 Windows SSH config

打开:

powershell 复制代码
notepad $env:USERPROFILE\.ssh\config

加入:

sshconfig 复制代码
Host pcl112
    HostName 192.168.206.112
    User pcljgy
    RequestTTY no
    ServerAliveInterval 30
    ServerAliveCountMax 3
    TCPKeepAlive yes
    LogLevel ERROR

测试:

powershell 复制代码
ssh -T pcl112 "echo ok"

理想输出只应该是:

text 复制代码
ok

如果出现欢迎语、乱码、conda 信息、颜色控制符,就说明远端 shell 启动脚本仍然污染输出。


4.4 远端宿主机补齐基础文件

登录远端宿主机:

powershell 复制代码
ssh pcljgy@192.168.206.112

在宿主机执行:

bash 复制代码
mkdir -p ~/.ssh ~/.gnupg
touch ~/.ssh/known_hosts
chmod 700 ~/.ssh ~/.gnupg
chmod 600 ~/.ssh/known_hosts
gpg --list-keys >/dev/null 2>&1 || true

4.5 清理远端宿主机 Cursor 残留

在 206.112 宿主机执行:

bash 复制代码
pkill -u "$(id -u)" -f cursor-server || true
pkill -u "$(id -u)" -f multiplex-server || true
pkill -u "$(id -u)" -f cursor-remote || true
pkill -u "$(id -u)" -f devcontainer-cli || true
pkill -u "$(id -u)" -f forwarder.js || true

rm -rf ~/.cursor-server
rm -rf /tmp/cursor-remote-ssh-*
rm -rf /tmp/devcontainer-cli-*
rm -rf /run/user/$(id -u)/cursor-remote-* 2>/dev/null || true

4.6 清理 Docker 容器内 Cursor 残留

如果容器 ID 是 f3673e625a77,在宿主机执行:

bash 复制代码
docker exec -u root f3673e625a77 sh -lc '
pkill -f cursor-server || true
pkill -f multiplex-server || true
pkill -f cursor-remote || true
pkill -f devcontainer-cli || true
pkill -f forwarder.js || true

rm -rf /root/.cursor-server
rm -rf /tmp/cursor-remote-ssh-*
rm -rf /tmp/devcontainer-cli-*
rm -rf /run/user/*/cursor-remote-* 2>/dev/null || true
'

如果容器里没有重要运行任务,可以重启容器:

bash 复制代码
docker restart f3673e625a77

4.7 修改 Cursor 设置

打开:

powershell 复制代码
notepad "$env:APPDATA\Cursor\User\settings.json"

加入或合并以下配置:

json 复制代码
{
  "remote.SSH.showLoginTerminal": false,
  "remote.SSH.useLocalServer": false,
  "remote.SSH.remoteServerListenOnSocket": false,
  "dev.containers.copyGitConfig": false,
  "remote.containers.copyGitConfig": false
}

重点配置说明:

json 复制代码
"remote.SSH.remoteServerListenOnSocket": false

用于避免 socket mode 下 socket 路径解析和任意 TCP 转发问题。

json 复制代码
"dev.containers.copyGitConfig": false,
"remote.containers.copyGitConfig": false

用于绕开 .gitconfig path undefined 相关问题。


4.8 正确重新连接流程

不要直接点 Cursor 首页的旧 Recent Project,例如:

text 复制代码
Container magatron (f3673e625a77)

应该按这个顺序:

text 复制代码
1. 打开 Cursor
2. Remote-SSH: Connect to Host...
3. 选择 pcl112 或 192.168.206.112
4. 等左下角显示已经 SSH 连接到远端宿主机
5. 再执行 Dev Containers: Attach to Running Container...
6. 选择 magatron / f3673e625a77
7. 再打开 /workspace 或 /root/workspace

5. 排查命令

5.1 判断 Docker 容器本身是否可进入

在远端宿主机执行:

bash 复制代码
docker ps -a | grep f3673e625a77
docker inspect -f '{{.State.Status}} {{.State.Running}} {{.State.ExitCode}} {{.Name}}' f3673e625a77
docker exec -it f3673e625a77 bash

如果 bash 不存在:

bash 复制代码
docker exec -it f3673e625a77 sh

如果手动 docker exec 都进不去,问题在 Docker / 容器本身,不是 Cursor。

如果手动 docker exec 能进去,但 Cursor 进不去,问题在 Cursor Remote Containers / 端口转发 / 缓存状态。


5.2 查看容器内 Cursor Server 日志

bash 复制代码
docker exec -u root f3673e625a77 sh -lc '
ls -lh /root/.cursor-server/
tail -200 /root/.cursor-server/*.log 2>/dev/null || true
'

5.3 检查远端宿主机资源

bash 复制代码
df -h
df -ih
free -h
ls -ld /tmp /run/user/$(id -u) ~

如果磁盘满了、inode 满了、/tmp 不可写,Cursor Server 也可能启动失败。


5.4 检查是否被 OOM 杀掉

bash 复制代码
dmesg -T | tail -100 | grep -iE "killed|oom|cursor|node"

6. 最短可执行修复版

Windows PowerShell

powershell 复制代码
taskkill /F /IM Cursor.exe
taskkill /F /IM ssh.exe

Rename-Item "$env:APPDATA\Cursor\User\globalStorage\anysphere.remote-containers" `
  "$env:APPDATA\Cursor\User\globalStorage\anysphere.remote-containers.bak" `
  -ErrorAction SilentlyContinue

远端宿主机

bash 复制代码
mkdir -p ~/.ssh ~/.gnupg
touch ~/.ssh/known_hosts
chmod 700 ~/.ssh ~/.gnupg
chmod 600 ~/.ssh/known_hosts

pkill -u "$(id -u)" -f cursor-server || true
pkill -u "$(id -u)" -f multiplex-server || true
pkill -u "$(id -u)" -f cursor-remote || true
pkill -u "$(id -u)" -f devcontainer-cli || true
pkill -u "$(id -u)" -f forwarder.js || true

rm -rf ~/.cursor-server
rm -rf /tmp/cursor-remote-ssh-*
rm -rf /tmp/devcontainer-cli-*
rm -rf /run/user/$(id -u)/cursor-remote-* 2>/dev/null || true

容器内清理

bash 复制代码
docker exec -u root f3673e625a77 sh -lc '
pkill -f cursor-server || true
pkill -f multiplex-server || true
pkill -f cursor-remote || true
pkill -f devcontainer-cli || true
pkill -f forwarder.js || true

rm -rf /root/.cursor-server
rm -rf /tmp/cursor-remote-ssh-*
rm -rf /tmp/devcontainer-cli-*
'

Cursor settings.json

json 复制代码
{
  "remote.SSH.showLoginTerminal": false,
  "remote.SSH.useLocalServer": false,
  "remote.SSH.remoteServerListenOnSocket": false,
  "dev.containers.copyGitConfig": false,
  "remote.containers.copyGitConfig": false
}

7. 最终结论

这次 Cursor 连接失败的核心不是 Docker 不可用,也不是 SSH 密码或网络问题。

更准确的结论是:

text 复制代码
Cursor Remote-SSH 能连上宿主机,
Docker 容器也能被 inspect,
容器内 Cursor Server 也能安装并监听端口;
但 Cursor Remote-Containers 的远程上下文丢失或缓存状态损坏,
导致 attach 容器时退回本地上下文,最终 .gitconfig 路径变成 undefined,
并伴随 socket mode、端口转发和旧进程残留问题。

推荐的解决策略是:

text 复制代码
清理本地 Cursor remote-containers 缓存
清理远端宿主机和容器内 Cursor 残留
关闭 socket mode 和 Git config 自动复制
不要从旧 Recent Project 直接恢复连接
先 Remote-SSH 到宿主机,再 Attach Running Container