背景
传统 VS Code Remote-SSH 的连接方式依赖本地到服务器的 SSH 长连接:
graph LR
A[本地 VS Code] --> B[SSH]
B --> C[Ubuntu 服务器]在跨地区网络、校园网、NAT 或代理环境下,SSH 连接可能出现以下问题:
- 长时间不操作后自动断开。
- 网络延迟较高时,终端输入和输出体验变差。
- 服务器没有公网 IP 或入站端口不方便开放。
- 本地网络切换后,SSH 连接容易中断。
VS Code Remote Tunnel 提供了另一种远程开发方式。它在服务器端运行 code tunnel,由服务器主动建立出站连接;本地 VS Code 再通过 Tunnel 连接服务器。
graph LR
A[本地 VS Code] --> B[VS Code Tunnel 服务]
B --> C[Ubuntu 服务器]这种方式不需要服务器开放公网入站端口,也不依赖传统 SSH 长连接,更适合高延迟或不稳定网络环境下的远程开发。
基准环境
本文基于以下环境:
1
2
3
4
| 服务器系统:Ubuntu 24.04
服务器架构:x86_64 / amd64
远程主机名:lab-server
VS Code 客户端:本地 VS Code Desktop
|
服务器上的 VS Code CLI 安装路径:
软链接路径:
安装 VS Code CLI
在 Ubuntu 24.04 服务器上执行:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
| mkdir -p ~/apps/vscode-cli ~/.local/bin
cd ~/apps/vscode-cli
curl -sL "https://code.visualstudio.com/sha/download?build=stable&os=cli-linux-x64" -o vscode_cli.tar.gz
tar -xzf vscode_cli.tar.gz
ln -sf "$HOME/apps/vscode-cli/code" "$HOME/.local/bin/code"
export PATH="$HOME/.local/bin:$PATH"
SHELL_NAME="$(basename "${SHELL:-}")"
case "$SHELL_NAME" in
zsh)
SHELL_RC="$HOME/.zshrc"
;;
bash)
SHELL_RC="$HOME/.bashrc"
;;
*)
SHELL_RC="$HOME/.profile"
;;
esac
PATH_LINE='export PATH="$HOME/.local/bin:$PATH"'
if [ -f "$SHELL_RC" ]; then
grep -qxF "$PATH_LINE" "$SHELL_RC" || echo "$PATH_LINE" >> "$SHELL_RC"
else
echo "$PATH_LINE" > "$SHELL_RC"
fi
code --version
|
如果能正常输出 VS Code CLI 版本,说明安装成功。
第一次启动 Remote Tunnel
第一次启动需要完成账号登录。服务器上执行:
1
| code tunnel --accept-server-license-terms --name lab-server
|
终端会显示一个登录链接和验证码。使用浏览器打开链接,使用 GitHub 或 Microsoft 账号登录。
登录成功后,终端会显示类似下面的地址:
1
| https://vscode.dev/tunnel/lab-server/...
|
此时说明 lab-server 已经可以通过 VS Code Remote Tunnel 访问。
测试完成后,可以按 Ctrl+C 停止前台进程。
安装为 systemd 用户服务
前台运行只适合临时测试。长期使用应该安装为 systemd user service。
执行:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| CODE="$HOME/apps/vscode-cli/code"
systemctl --user stop code-tunnel 2>/dev/null || true
"$CODE" tunnel service uninstall 2>/dev/null || true
systemctl --user daemon-reload
"$CODE" tunnel unregister 2>/dev/null || true
"$CODE" tunnel service install --accept-server-license-terms --name lab-server
systemctl --user daemon-reload
systemctl --user enable --now code-tunnel
systemctl --user status code-tunnel --no-pager
"$CODE" tunnel status
|
如果看到:
1
| Active: active (running)
|
说明 Remote Tunnel 服务已经正常运行。
设置开机自启
为了让服务器重启后 Remote Tunnel 自动恢复,需要启用 linger:
1
2
3
| sudo loginctl enable-linger "$USER"
loginctl show-user "$USER" | grep Linger
|
期望输出:
这样即使用户没有手动 SSH 登录,code-tunnel.service 也可以在后台运行。
本地 VS Code 连接服务器
本地 VS Code Desktop 安装扩展:Remote - Tunnels,然后按 Ctrl/Cmd + Shift + P 打开 Command Palette 然后选择 Remote Tunnels: Connect to Tunnel。随后选择和服务器端相同的 GitHub 或 Microsoft 账号登录。之后选择 lab-server (服务端配置完成及客户端登录账号后会自动出现在列表中)。连接成功后,即可打开远程项目目录。此时 VS Code 的编辑器、文件浏览器、终端和扩展都运行在远程 Ubuntu 24.04 服务器环境中。
常用管理命令
查看服务状态:
1
| systemctl --user status code-tunnel --no-pager
|
查看最近日志:
1
| journalctl --user -u code-tunnel -n 100 --no-pager
|
实时查看日志:
1
| journalctl --user -u code-tunnel -f
|
重启服务:
1
| systemctl --user restart code-tunnel
|
停止服务:
1
| systemctl --user stop code-tunnel
|
卸载服务:
1
2
| "$HOME/apps/vscode-cli/code" tunnel service uninstall
systemctl --user daemon-reload
|
注销当前 Tunnel:
1
| "$HOME/apps/vscode-cli/code" tunnel unregister
|
查看 Tunnel 状态:
1
| "$HOME/apps/vscode-cli/code" tunnel status
|
常见问题
提示 unit 文件变化
如果看到:
1
2
| Warning: The unit file, source configuration file or drop-ins of code-tunnel.service changed on disk.
Run 'systemctl --user daemon-reload' to reload units.
|
执行:
1
2
| systemctl --user daemon-reload
systemctl --user restart code-tunnel
|
本地 VS Code 看不到 lab-server
先确认服务器服务是否运行:
1
| systemctl --user status code-tunnel --no-pager
|
再确认 Tunnel 状态:
1
| "$HOME/apps/vscode-cli/code" tunnel status
|
如果仍然无法看到,重新注册:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| CODE="$HOME/apps/vscode-cli/code"
systemctl --user stop code-tunnel 2>/dev/null || true
"$CODE" tunnel service uninstall 2>/dev/null || true
"$CODE" tunnel unregister 2>/dev/null || true
systemctl --user daemon-reload
"$CODE" tunnel service install --accept-server-license-terms --name lab-server
systemctl --user daemon-reload
systemctl --user enable --now code-tunnel
"$CODE" tunnel status
|
服务正常但重启后没有自动恢复
检查 linger:
1
| loginctl show-user "$USER" | grep Linger
|
如果不是 Linger=yes,执行:
1
| sudo loginctl enable-linger "$USER"
|
推荐使用方式
Remote Tunnel 负责远程开发连接,适合日常编辑、终端操作、运行脚本和调试代码。
长时间任务仍然建议放在 tmux 中运行:
重新连接:
这样即使 VS Code 客户端断开,远程任务也可以继续运行。
完整安装命令
下面是一套从零开始的完整安装命令,适用于 Ubuntu 24.04 x86_64 服务器。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
| set -e
SERVER_NAME="lab-server"
CODE_DIR="$HOME/apps/vscode-cli"
CODE_BIN="$CODE_DIR/code"
mkdir -p "$CODE_DIR" "$HOME/.local/bin"
cd "$CODE_DIR"
curl -sL "https://code.visualstudio.com/sha/download?build=stable&os=cli-linux-x64" -o vscode_cli.tar.gz
tar -xzf vscode_cli.tar.gz
ln -sf "$CODE_BIN" "$HOME/.local/bin/code"
# Make code available in the current script immediately
export PATH="$HOME/.local/bin:$PATH"
# Persist PATH for the user's current shell: bash / zsh / fallback profile
SHELL_NAME="$(basename "${SHELL:-}")"
case "$SHELL_NAME" in
zsh)
SHELL_RC="$HOME/.zshrc"
;;
bash)
SHELL_RC="$HOME/.bashrc"
;;
*)
SHELL_RC="$HOME/.profile"
;;
esac
PATH_LINE='export PATH="$HOME/.local/bin:$PATH"'
if [ -f "$SHELL_RC" ]; then
grep -qxF "$PATH_LINE" "$SHELL_RC" || echo "$PATH_LINE" >> "$SHELL_RC"
else
echo "$PATH_LINE" > "$SHELL_RC"
fi
echo "PATH updated in: $SHELL_RC"
"$CODE_BIN" --version
systemctl --user stop code-tunnel 2>/dev/null || true
"$CODE_BIN" tunnel service uninstall 2>/dev/null || true
"$CODE_BIN" tunnel unregister 2>/dev/null || true
systemctl --user daemon-reload
"$CODE_BIN" tunnel service install --accept-server-license-terms --name "$SERVER_NAME"
systemctl --user daemon-reload
systemctl --user enable --now code-tunnel
sudo loginctl enable-linger "$USER"
systemctl --user status code-tunnel --no-pager
"$CODE_BIN" tunnel status
|
本地 VS Code 连接:
graph TD
A[安装 Remote - Tunnels 扩展] --> B[Ctrl/Cmd + Shift + P 打开 Command Palette]
B --> C[输入或选择 Remote Tunnels: Connect to Tunnel...]
C --> D[选择服务端 lab-server]
D --> E[打开远程项目目录]