第14章 Zed 远程开发——SSH 工作流
远程开发允许你在本地运行 Zed 的同时,编辑远程服务器上的代码。由于界面在你本机上运行,响应速度依然流畅;而语言服务器、任务及终端则运行在远程服务器上。
日常使用建议将远程开发与任务(Tasks)、终端和调试器(Debugger)配合使用。
概述
远程开发需要两台计算机:运行 Zed 界面的本地机器,以及运行 Zed 无头服务器(headless server)的远程主机。两者通过 SSH 通信,因此你必须能使用 SSH 从本地机器连接到远程服务器,才能使用此功能。

本地机器负责运行 Zed 界面、与语言模型交互、使用 Tree-sitter 解析并高亮代码,以及存储未保存的更改和最近打开的项目。源代码、语言服务器、任务和终端全部运行在远程服务器上。AI 功能(包括 Agent Panel 和 Inline Assistant)同样适用于远程会话。
注意: 早期的远程开发版本通过 Zed 的服务器中转流量。从 Zed v0.157 开始,该模式已不再可用。
设置
- 下载并安装最新版 Zed,版本至少需为 v0.159。
- 使用 {#kb projects::OpenRemote} 快捷键打开“远程项目”对话框。
- 点击“连接新服务器”,并输入你通常用于 SSH 连接该服务器的命令。可传递的选项参见 支持的 SSH 选项。
- 本地机器将尝试使用 PATH 中的
ssh二进制文件连接到远程服务器。如果连接成功,Zed 会在远程主机上下载并启动服务器。 - Zed 服务器启动后,系统会提示你选择在远程服务器上打开的路径。
注意:Zed 目前对打开超大目录的处理效果不佳(例如包含超过 100,000 个文件的
/或~)。我们正在努力改善此问题,在此期间建议仅打开特定项目或大型单仓(mono-repo)的子文件夹。
对于不需要特定 SSH 参数的简单场景,你可以运行 zed ssh://[<user>@]<host>[:<port>]/<path> 直接打开远程文件夹或文件。CLI 也支持 scp 风格的写法,如 zed ssh://[<user>@]<host>:~/project 或 zed ssh://[<user>@]<host>:/absolute/path。若要热链到 SSH 项目,请使用格式为 zed://ssh/[<user>@]<host>[:<port>]/<path> 的链接。
支持的平台
远程机器必须能够运行 Zed 服务器。以下平台应当适用,但请注意我们并未穷尽测试所有 Linux 发行版:
- macOS Catalina 或更高版本(Intel 或 Apple Silicon)
- Linux(x86_64 或 arm64,暂不支持 32 位平台)
- Windows(x86_64 或 arm64)
配置
远程服务器列表存储在你的设置文件 {#kb zed::OpenSettings} 中。你可以使用远程项目对话框 {#kb projects::OpenRemote} 编辑此列表,这提供了一定的健壮性——例如,在写入设置文件之前,它会检查连接是否成功建立。
{
"ssh_connections": [
{
"host": "192.168.1.10",
"projects": [{ "paths": ["~/code/zed/zed"] }]
}
]
}
Zed 会调用系统路径中的 ssh,因此它会继承 ~/.ssh/config 中针对特定主机的任何配置。不过,如果需要覆盖某些设置,你可以为每个连接配置以下额外选项:
{
"ssh_connections": [
{
"host": "192.168.1.10",
"projects": [{ "paths": ["~/code/zed/zed"] }],
// 传给 ssh 主进程的任意参数
"args": ["-i", "~/.ssh/work_id_file"],
"port": 22, // 默认为 22
// 默认使用你本地机器的用户名
"username": "me"
}
]
}
每个连接还有两个 Zed 特有的选项:upload_binary_over_ssh 和 nickname:
{
"ssh_connections": [
{
"host": "192.168.1.10",
"projects": [{ "paths": ["~/code/zed/zed"] }],
// 默认情况下,Zed 会在远程服务器上直接从网络下载 server 二进制文件。
// 设为 true 时,会先下载到你的笔记本,再通过 SSH 上传过去。
// 当远程服务器的网络访问受限时,这个选项很有用。
"upload_binary_over_ssh": true,
// 显示在 Zed 界面中,便于区分多个主机。
"nickname": "lil-linux"
}
]
}
如果你用命令行连接主机,例如 zed ssh://192.168.1.10/~/.vimrc,Zed 会从设置文件中查找与命令行 URL 的主机/用户名/端口匹配的第一个连接,并应用其中的额外选项。
另外需要注意的是,虽然你可以在命令行中传入密码(如 zed ssh://user:password@host/~),但我们不支持把密码写入设置文件。如果你需要反复连接同一台主机,建议配置基于密钥的身份验证。
在 Windows 上进行远程开发(SSH)
Windows 版 Zed 支持 SSH 远程连接,并会在需要时提示输入凭据。
如果遇到身份验证问题,请确认你的 SSH 密钥代理正在运行(例如 ssh-agent 或 Git 客户端自带的代理),并且 ssh.exe 已加入 PATH。
Windows 上的 SSH 问题排查
提示输入凭据时,会弹出图形化的 askpass 对话框。如果对话框没有出现,请检查凭据管理器是否有冲突,以及终端是否阻止了 GUI 提示。
WSL 支持
Zed 在 Windows 上原生支持打开 WSL 内的文件夹。
在 WSL 中打开本地文件夹
要在 WSL 容器内打开本地文件夹,请调用 {#action projects::OpenFolderInWsl} 动作并选择要打开的文件夹。随后会列出一个可用的 WSL 发行版列表,供你选择在该发行版中打开文件夹。
打开 WSL 内已有的文件夹
如果文件夹已经在 WSL 容器内,调用 {#action projects::OpenWsl} 动作并选择对应的 WSL 发行版。该发行版会出现在 Remote Projects 窗口中,之后即可在其中打开对应文件夹。
端口转发
如果需要从本地机器访问远程服务器的某些端口,可以在配置文件中设置端口转发。这在开发网站时尤其有用,因为边开发边在浏览器中加载站点会很方便。
{
"ssh_connections": [
{
"host": "192.168.1.10",
"port_forwards": [{ "local_port": 8080, "remote_port": 80 }]
}
]
}
配置后,本地机器发往 localhost:8080 的请求将被转发到远程机器的 80 端口。底层机制是调用 ssh 时附带 -L 参数。
这些端口默认绑定到 localhost,因此与开发机在同一网络中的其他计算机无法访问。可以通过设置 local_host 将端口绑定到其他网卡,例如设为 0.0.0.0 则绑定到所有本地网卡。
{
"ssh_connections": [
{
"host": "192.168.1.10",
"port_forwards": [
{
"local_port": 8080,
"remote_port": 80,
"local_host": "0.0.0.0"
}
]
}
]
}
这些端口在远程主机上也默认绑定到 localhost 网卡。如需更改,还可以设置 remote_host:
{
"ssh_connections": [
{
"host": "192.168.1.10",
"port_forwards": [
{
"local_port": 8080,
"remote_port": 80,
"remote_host": "docker-host"
}
]
}
]
}
Zed 设置
打开远程项目时,有三处关键配置位置:
- 本地机器上的 Zed 设置(macOS 位于
~/.zed/settings.json,Linux 位于~/.config/zed/settings.json)。 - 远程服务器上的 Zed 设置(路径同上)。
- 项目设置(位于项目的
.zed/settings.json或.editorconfig中)。
本地和服务器端的 Zed 都会读取项目设置,但彼此的主设置文件互不感知。
具体使用哪个设置文件,取决于你想配置的内容:
- 项目级配置用于影响项目本身的设定,如缩进规则、格式化程序或 Language Server 的选择等。
- 服务器级配置用于影响服务器环境的设定,如 Language Server 的路径、代理设置等。
- 本地配置用于影响 UI 的设定,如字体大小等。
此外,本地安装的扩展会自动同步到远程服务器,确保 Language Server 等组件正常运行。
代理配置
由于网络策略可能不同,远程服务器不会使用本地机器的代理配置。如果远程服务器需要代理才能访问互联网,必须在服务器本身进行配置。
通常情况下,远程服务器已预配置了代理环境变量。Zed 在下载 Language Server、与 LLM 模型通信等场景下会自动使用这些变量。
如有必要,你可以在服务器的 shell 配置文件(例如 ~/.bashrc)中设置这些环境变量:
export http_proxy="http://proxy.example.com:8080"
export https_proxy="http://proxy.example.com:8080"
export no_proxy="localhost,127.0.0.1"
或者,在远程机器的 Zed 设置文件中配置代理(Linux 为 ~/.config/zed/settings.json,macOS 为 ~/.zed/settings.json):
{
"proxy": "http://proxy.example.com:8080"
}
支持的代理类型及更多配置选项,请参阅 代理文档。
初始化远程服务器
填好 SSH 选项后,Zed 会在本地调用 ssh,用你提供的选项建立 ControlMaster 连接。
SSH 需要的任何交互提示(如确认主机密钥、输入密钥密码等)都会直接显示在界面中。
主连接建立后,Zed 会检查远程服务器二进制文件是否存在于远程的 ~/.zed_server 目录,以及版本是否与你当前使用的 Zed 一致。
如果文件不存在或版本不匹配,Zed 会尝试下载最新版本。默认从 https://zed.dev 直接下载;但如果你在设置中为该服务器配置了 {"upload_binary_over_ssh":true},则会先把二进制文件下载到本地,再上传到远程服务器。
你也可以自己维护这个服务器二进制文件:既可以从 GitHub 下载我们预构建的版本,也可以自行构建:
cargo build --release --package remote_server
llvm-objcopy --strip-debug target/release/remote_server
去除调试符号这一步与 script/bundle-linux 中的打包流程一致,能让二进制文件的体积接近 Zed 官方预构建版本。建议使用 llvm-objcopy,因为 GNU objcopy 可能无法识别较新版本的 LLVM 生成的 CREL 段。
官方 Linux 发行版构建的是 musl 静态链接的远程服务器。如果需要同样的效果,请参照 script/bundle-linux 中当前使用的 target 和编译参数;以 x86-64 Linux 为例:
RUSTFLAGS="-C target-feature=+crt-static" cargo build --release --package remote_server --target x86_64-unknown-linux-musl
llvm-objcopy --strip-debug target/x86_64-unknown-linux-musl/release/remote_server
如果你这样做,必须将其上传到服务器上的 ~/.zed_server/zed-remote-server-{RELEASE_CHANNEL}-{VERSION},例如 ~/.zed_server/zed-remote-server-stable-0.217.3+stable.105.80433cb239e868271457ac376673a5f75bc4adb1。版本号必须与你正在使用的 Zed 自身版本完全匹配。
维护 SSH 连接
服务器初始化完成后,Zed 会建立新的 SSH 连接(复用现有的 ControlMaster)来运行远程开发服务器。
每个连接都尝试以代理模式运行开发服务器。该模式会在守护进程未运行时启动它,若已运行则重新连接。这样一来,当连接断开并重启时,你可以无中断地继续工作。
如果重新连接失败,则不会复用该守护进程。不过,未保存的更改默认会持久化到本地,因此你不会丢失工作成果。你始终可以稍后重新连接到项目,Zed 会恢复未保存的更改。
如果你遇到连接问题,应该能在 Zed 日志中查看更多信息(快捷键 cmd-shift-p Open Log)。如果你看到异常现象,请提交 GitHub issue 或在 Discord 的 #support 论坛中寻求帮助。
支持的 SSH 选项
在底层,Zed 调用 ssh 命令连接远程服务器。我们为每个项目创建一个 SSH 控制主连接,并使用它来复用 Zed 协议本身、你打开的终端以及运行任务所需的 SSH 连接。我们会从你的 SSH 配置文件中读取设置,但如果你想为 SSH 控制主连接指定额外选项,可以配置 Zed 来设置它们。
在“连接新服务器”对话框中输入时,你可以使用 bash 风格的引号来传递包含空格的选项。创建服务器后,它会添加到设置文件中的 "ssh_connections": [] 数组里。你可以直接编辑设置文件来更改 SSH 连接配置。
支持的选项:
-p/-l- 等同于在主机字符串中传递端口和用户名。-L/-R用于端口转发-i- 用于指定特定的密钥文件-o— 设置自定义选项-J/-w— 代理 SSH 连接-F— 指定ssh_config配置文件- 此外还支持:
-4、-6、-A、-B、-C、-D、-I、-K、-P、-X、-Y、-a、-b、-c、-i、-k、-l、-m、-o、-p、-w、-x、-y
注意,我们故意禁用了部分选项(例如 -t 或 -T),这些选项会由 Zed 自动处理。
已知限制
- 无法通过输入
zed命令来从远程终端中打开文件。
参见
- 运行与测试:在远程工作时运行任务、终端命令和调试器会话。
- Git Worktrees:创建并在联动的 Git worktrees 之间切换。当远程连接处于激活状态时,Zed 支持在远程项目中使用 worktree 选择器。
- 配置 Zed:管理共享设置和项目设置,包括
.zed/settings.json。 - Agent Panel:在远程项目中使用 AI 工作流。
- zed.dev 上的远程开发:产品概览及版本更新信息。