远程开发实践
前言
作为一个软件开发者,在了解了远程开发的优势后就知道它多么香。Jetbrain 系的软件可以远程开发,vscode 的系的软件也可以,不过我更喜欢 vscode 系,因为只需要通过切换不同配置即可让 vscode 化身为 IDEA、GoLand、Pycharm、WebStorm 等 IDE,并且它还是免费的。
对比本地开发,远程开发的好处有:
- 只需要在远程机上配置一次开发环境即可,一次配置,处处开发
- 其他诸如 Git、Docker、代码仓库等也都只需要配置一次
- 不挑本地机的配置,只要能装类 vscode 软件即可
- 本地机可以运行在任何系统上,远程机可以配置在 Linux 系统上,统一开发环境
远程开发和本地开发体验基本一致,各种插件可以使用,代码补全、调试、测试体验都一样,并且会自动转发端口,即使服务运行在远程机上,也可以在本地使用 localhost 访问。
因为远程开发原本就是 vscode 的功能,所以所有以 vscode 衍生出来的 IDE 都可以用远程开发,如:Trae、Trae CN、灵码IDE等,配置起来也都是一样的方式,这里就以 Trae CN 为例。
1. Trae 远程开发
1.1. 安装 Trae CN
Trae CN 是 Trae 的国内版本,它的功能和 Trae 的差别仅在 AI 模型上的不同。Trae 主要面向港澳和国外用户,对接的主要是国外大模型,如:OpenAI、Anthropic、Google 等;Trae CN 主要面向国内用户,对接的是国内大模型,如:豆包、Deepseek。不过这两个都支持添加模型,目前 Trae 已经收费了,免费版不够用,而 Trae CN 目前还是免费的,未来应该也是会收费的,因为阿里的 灵码IDE 已经收费了。
Trae CN 安装非常简单,只需要下载安装包,然后运行即可。
1.2. 远程系统安装
为表述方便,Trae CN 在下文简称为 trae。
trae 支持通过 SSH 连接到远程 Linux 主机,也支持通过 SSH 连接到远程 WSL 主机。为了方便以后迁移,这里我使用的是 VMware 虚拟机,毕竟这个也免费了。
安装虚拟系统可以查看VM虚拟机安装ubuntu22.04.1,可以选择最新的系统版本下载安装。如果想使用 WSL 也可以看这个WSL2使用。
1.3. SSH 远程连接
使用命令ssh-keygen -t ed25519 -C "winmi"
生成密钥,这里winmi
表示为主机名,可以随意设置也可以不设置。然后复制公钥到远程机ssh-copy-id -i /c/Users/mee/.ssh/vmos/id_ed25519.pub root@192.168.0.28
,因为前一步把密钥存储在了/c/Users/mee/.ssh/vmos
目录下,如果需要-i
指定密钥位置,如果没有修改位置也可以无需-i
参数。
打开 trae,点击左边侧边栏的远程资源管理器
添加连接,输入ssh root@192.168.0.28 -A
保存连接,之后点击⚙
修改远程连接配置会打开一个文件,其实就是~/.ssh/config
文件,内容如下:
# GitHub
# vmos 开发虚拟机
Host vmos
HostName 192.168.0.28
IdentityFile C:\Users\mee\.ssh\vmos\id_ed25519
User root
ForwardAgent yes
-A
参数其实就是设置ForwardAgent
,它的作用是将本机的 SSH 代理转发到远程机上,这样就可以在远程机上使用本机的 SSH 代理了。说人话就是,例如在本地机上配置了到 GitHub 的 SSH 密钥,那么在远程机上就无需再配置,可以直接使用本地机的 SSH 密钥。
1.4. 远程开发
在远程机上配置好各种开发环境,然后可以正常开发了。
2. vscode 远程开发
2.1 几种远程方式的区别
仔细了解过 vsode 远程开发后才发现它有多强大,其他衍生品的远程开发功能都是阉割版的。
vscode 的远程开发有 5 中方式:
- SSH:在远程 Linux 主机中运行 vscode 服务器,依赖 SSH;
- WSL:在远程 Windows 主机的 Linux子系统(WSL) 中运行 vscode 服务器,依赖 SSH;
- Container:在远程 Docker 容器中运行 vscode 服务器;
- Tunnel:在远程 Linux 或 WSL 中运行 vscode 服务器,不依赖 SSH;
- Codespaces:在 GitHub 提供的 Codespaces 中运行 vscode 服务器;
那么,用那种方式好呢?
这就要分情况了:
- 正常情况下最推荐的方式是 SSH/WSL,一个高性能远程主机搭配普通配置的笔记本电脑,让你移动开发也能流畅丝滑。不过有两个限制:如果主机在内网需要解决内网穿透问问题、移动端电脑要能安装 vscode 和支持 SSH 协议。
- 其次就是 Tunnel(隧道),它需要走 GitHub 或者 Microsoft 认证,所以你至少得有任一账号,并且隧道模式是经过微软的专有网络,所以即使远程主机在内网也没关系,好处就是:不需要内网穿透 、也不需要SSH,这意味着你可以通过网页端的 vscode也能连接到远程开发,iPad 也能成为生产力。不过缺点就是因为要经过微软的网络,即使你本地和远程机处在同一内网下,也会在外网绕一圈,实测延迟挺高的。跑跑简单的工程或者脚本问题不大,太大的项目就不建议这么做了。
- 至于容器中开发,这一般是有特殊需求的,比如:需要同时运行多个服务端,但又需要相互隔离。这就非常有用了,通常用在需要快速的验证或者复现某个环境时。
- Codespaces 这个因为要付费,虽然有免费额度,但是长期开发的话那点临时额度根本不够用,如果临时需要启用一些还是可以的。免费的不能作为生产力,付费的就另说了。
2.2. 隧道模式
这里重点说一下隧道模式(Tunnel),某些情况下还是挺有用的,比如出门在外手头上没有电脑,需要紧急处理/验证一些代码的时候,此时任何一个可以打开浏览器上网的设备都可以拿来用。
一般当你安装了任一种桌面版的 vscode 都自带了 Tunnel,打开方式点击左下角的头像打开远程隧道访问
,有两个选项:启用此会话
、作为服务安装
。前者是临时启动隧道服务,下次打开 vscode 不会自动开启隧道;后者是每次打开 vscode 都会自动启动隧道。但无论哪种都是让你当前这个设备作为 vscode 服务端的。
可远程主机是 Linux 服务器,没有界面,装不了桌面版,此时就可以单独安装CLI工具了。安装方式参考官方文档,这里不再赘述。下载下来是一个压缩包,解压后就只有一个code
可执行文件,可以放在任意位置,运行code tunnel
就可以启动隧道,查看文档探索更多使用方式。
一开始我想把它注册成为服务,使之可以开机自启,能用服务启动/关闭/查看状态/查看日志等。但仔细想了想,其实完全没有必要每次都开机自启,因为绝大多数时候都是使用 SSH 模式,Tunnel 仅仅是应急,应该需要的时候启动即可。而为了能够便捷使用可以用脚本管理:
#!/bin/bash
CMD="$HOME/.bin/code tunnel"
LOG="$HOME/.log/tunnel.log"
start() {
if pgrep -f "code tunnel" > /dev/null; then
echo "❗ code tunnel 已在运行 (PID=$(pgrep -f 'code tunnel'))"
echo "🌐 隧道访问地址: https://vscode.dev/tunnel/<隧道名>"
else
echo "🚀 正在启动 code tunnel..."
nohup $CMD > "$LOG" 2>&1 &
sleep 1
if pgrep -f "code tunnel" > /dev/null; then
echo "✅ 启动成功 (PID=$(pgrep -f 'code tunnel'))"
echo "🌐 隧道访问地址: https://vscode.dev/tunnel/<隧道名>"
else
echo "❌ 启动失败,请检查日志:$LOG"
fi
fi
}
stop() {
if pgrep -f "code tunnel" > /dev/null; then
echo "🛑 正在关闭 code tunnel..."
pkill -f "code tunnel"
echo "✅ 已关闭"
else
echo "ℹ️ code tunnel 未在运行"
fi
}
restart() {
echo "🔄 正在重启 code tunnel..."
stop
sleep 1
start
}
status() {
if pgrep -f "code tunnel" > /dev/null; then
echo "✅ code tunnel 正在运行 (PID=$(pgrep -f 'code tunnel'))"
ps -fp "$(pgrep -f 'code tunnel')"
else
echo "⛔ code tunnel 未运行"
fi
}
log() {
echo "📜 正在实时查看日志:$LOG"
tail -f "$LOG"
}
# 分发命令
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
status
;;
log)
log
;;
*)
echo "用法: $0 {start|stop|restart|status|log}"
exit 1
;;
esac
chmod +x ~/tunnel
给执行权限后,就可以使用./tunnel {start|stop|restart|status|log}
任一命令执行了。
第一次使用时需要登录账号,所以必须前台运行一次code tunnel
,完成登录后自动启动隧道,然后可以ctrl+c
关闭隧道。之后再运行code tunnel
就不用再登录了。实测发现,在登录过后,如果你移动了 code 命令的位置,之后再运行code tunnel
就又要鉴权了,所以最好确定好位置后再登录,如果移动了位置,一定要注意再前台执行一次,然后登录。
官方提示:
- 隧道限制: 为避免滥用,一个账号最多只能开启 5 个隧道,超过数量后,最早未使用的隧道将自动被移除。
- 访问限制: 不能多个用户或客户端同时访问同一远程示例,服务器实例设计为一次只能由一个用户或客户端访问。
3. code-server
上面 vscode 的隧道模式基本上是能用了,只是不好用,因为延迟太高了,要是不通外网还用不了。在电脑浏览器上打开它是没什么问题,但是在我的 iPad 的上打开就之中连不上隧道,又折腾了良久未能解决,偶然间让我发现了 code-server。
这是一个运行在 web 上的 vscode 开源项目,它是在 vscode 开源版的基础上做了补丁,使之更适合自托管。
使用上基本和 vscode 隧道模式一致,但因为它和微软无关,所以网络上是直连的,使用的是 Websocket 协议,延迟相当低,实际开发体验和 vscode SSH 模式并无二致。
3.1 安装
直接参考官方文档,安装方式非常多,可以在 Linux/Macos、Windows、Node.js、Docker 等环境中部署,基本上都是一条命令完成。
接下来以在 Linux 环境中部署为例:
# 一键安装(期间只需要输入一次 sudo 密码即可)
curl -fsSL https://code-server.dev/install.sh | sh
Tip: 升级的话也只需要把上面的命令再运行一遍即可。它其实就是去下载最新的.deb
安装包放在~/.cache/code-server
目录下,然后执行sudo dpkg -i ~/.cache/code-server/code-server_x.x.x_amd64.deb
安装。
安装完成后,配置文件在~/.config/code-server/config.yaml
中,内容如下:
bind-addr: 127.0.0.1:8080
auth: password
password: maye
cert: false # 表示不使用证书
它默认监听在127.0.0.1
,如果你有反向代理服务器可以配置转发,否则就需要更改监听地址,可以改成具体地址如:192.168.0.68
这表示只会监听 LAN 网卡的流量,或者监听所有网卡的流量使用:0.0.0.0
。更多说明请看文档。
3.2 运行
一开始先临时启动执行code-server
即可在前台运行,按下ctrl+c
停止。如果想让它开机自启,就注册为系统服务:
# 这将 code-server 注册为系统服务(允许开机自启),并立刻启动
sudo systemctl enable --now code-server@$USER
# 重启
sudo systemctl restart code-server@$USER
# 停止
sudo systemctl stop code-server@$USER
3.3 访问
然后可以在任意浏览器(推荐 Chrome 或 Edge)访问如:http://192.168.0.68:8080
,输入配置的密码mayee
即可看到一个在线的 vscode,使用方式跟桌面版的差不多,一样可以启动、调试、装插件、代码补全、AI辅助。
不过,每次刷新页面时右下角会有个提示:
code-server is being accessed in an insecure context. Web views, the clipboard, and other functionality may not work as expected.
这提示是浏览器的安全提示,但是每次都出现有点烦人,要想解决这个问题有两方案:
- 直接修改浏览器设置,让它不要再提示了。
- 配置证书,使用 https 访问。
那我们就以简单为主先来第 1 种方案,对于 Chrome 浏览器就在地址栏输入chrome://flags
,对于 Edge 浏览器就输入edge://flags
,然后搜索Insecure origins treated as secure
,在文本框中填入你信任的地址http://192.168.0.68
并启用该选项,接着重启浏览器再访问就不会有提示了。
但是,你会发现之后每次启动浏览器时,都会显示一个横幅,大意是:警告你启用了一个不安全的功能,为了安全最好关掉它。好嘛,关掉了一个弹窗多了一个横幅,虽然没有之前的提醒频率高,但这么做总归感觉不太好,有点像“野路子”。既然野路子不行,那咱就试试正规军的法子,给它配置证书。
3.4 证书
证书配置有 3 种方式,任选一种即可,推荐使用第 3 种方式。
3.4.1 自配置(不推荐)
通过code-server -h
命令可以看到它的所有参数描述,我们关注如下几个参数:
- cert: 证书的路径,如果配置为 none 则会自动生成一个自签证书。
- cert-host: 当使用自动生成的自签证书时的主机名。
- cert-key: 当使用非自动生成的自签证书时的证书密钥。
- trusted-origins: 禁用对可信来源的身份验证来源检查,当无法访问反向代理配置时很有用。
那么通过对这几个值的配置,配置证书就变得简单了。例如,我为code.dev.lan
这个域名配置证书,那么config.yaml
文件就可以编辑为如下内容:
bind-addr: 192.168.0.68:443
auth: password
password: maye
cert: none
cert-host: code.dev.lan
trusted-origins: ['code.dev.lan']
然后重启 code-server,一定要保证code.dev.lan
能被正确解析到192.168.0.68
,可以配置在你的本机 host 文件中,之后就可以通过https://code.dev.lan
访问了。
这样是可以,但这只能作用于 code-server,如果未来想用域名访问主机上的其他服务仍需配置。既然都打算“正规军”了,干脆一步到位,使用反向代理服务器配置。
3.4.2 Nginx(不推荐)
使用sudo apt update && sudo apt-get nginx -y
直接安装,不要用 docker 部署 nginx,因为我们的 coder-server 是部署在宿主机,容器中的网络是隔离,没法转发到宿主机的 ip,除非 code-server 也用 docker 部署,那 nginx 也可以用 docker 部署。安装完成后访问http://192.168.0.68
就可以看到 nginx 的欢迎页了。
如果你打算把 code-server 暴露在公网访问,那么可以申请一个免费域名,然后使用Let's Encrypt申请证书并做好自动续期,或者购买付费域名,一般都有一年有效期的免费证书,并且自动监控到期提醒,到期后申请新的免费证书即可。
不过,我并不打算把 code-server 暴露在公网,多数时间都是在内网访问,如果出门在外也可以通过 SS 节点或者 Tailscale 穿透回内网,那么我也就不需要购买域名,证书用自签的就好了。
我们可以使用开源项目mkcert来生成自签证书,首先要安装 mkcert,以 Ubuntu 系统为例,其他系统安装方式参照文档。
# 先安装依赖工具
sudo apt install libnss3-tools
# 然后安装 homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# 把 homebrew 添加到环境变量
echo >> /home/maye/.bashrc
echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >> /home/maye/.bashrc
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
# 安装 homebrew 的依赖
sudo apt-get install build-essential
# 推荐安装 GCC (非必须操作)
brew install gcc
# 安装 mkcert
brew install mkcert
安装好了 mkcert 后,就可以生成自签证书了:
# 生成系统根证书(有效期10年),会自动安装到系统根证书目录并信任
mkcert -install
# 创建目录用于存放域名证书
mkdir -p ~/.ssl/dev.lan
# 生成域名证书(证书将作用与 主域名: dev.lan 和 泛域名: *.dev.lan)
mkcert -key-file ~/.ssl/dev.lan/key.pem -cert-file ~/.ssl/dev.lan/cert.pem dev.lan ‘*.dev.lan’
于是就在~/.ssl/dev.lan
目录下生成了域名证书和密钥,证书有效期 90 天。
接着增加 Nginx 配置,创建一个文件如/etc/nginx/sites-available/code-server
:
server {
listen 80;
server_name code.dev.lan;
# 自动跳转 HTTP 到 HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name code.dev.lan;
ssl_certificate /home/maye/.ssl/dev.lan/cert.pem;
ssl_certificate_key /home/maye/.ssl/dev.lan/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://127.0.0.1:2333/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
}
}
然后检查配置sudo nginx -t
,没问题后创建软连接sudo ln -s /etc/nginx/sites-available/code-server /etc/nginx/sites-enabled/
,重载配置sudo nginx -s reload
或sudo systemctl reload nginx
。
在 Nginx 中配置过证书就不必在 code-server 配置证书了,因此~/.config/code-server/config.yaml
内容如下:
bind-addr: 127.0.0.1:2333
auth: password
password: maye
cert: false
locale: 'zh-cn'
disable-getting-started-override: true
link-protection-trusted-domains: ['192.168.0.*']
disable-telemetry: true
disable-workspace-trust: true
force: true
app-name: Codev
welcome-text: '死鬼,你来啦~'
重启 code-server sudo systemctl restart code-server@$USER
,此时就可以打开浏览器访问https://code.dev.lan
了,然后,,然后就发现浏览器还是提示无法验证code.dev.lan
的身份,为什么呢?
这个提示是由浏览器发出的,因为根证书并没有被浏览器信任,所以就提示无法验证code.dev.lan
的身份。
也好解决,找到 mkcert 生成的根证书~/.local/share/mkcert/rootCA.pem
然后导入到系统即可,以 Windows 为例:
- 修改文件名为
rootCA.crt
,然后双击安装; - 点击
安装证书
->本地计算机
->将所有的证书都放在下列存储
->受信任的根证书颁发机构
; - 重启浏览器访问
https://code.dev.lan
。
可是*.dev.lan
这个域名的证书有效期只有 90 天,到期之后需要使用mkcert
命令重新申请,把新证书放到之前的位置后,需要重载 Nginx 配置。
如果手动做这个事还是挺麻烦的,你当然可以使用certbot来完成自动监控证书到期时间以及续期。可这还是有点麻烦,强烈推荐下面的方式。
3.4.3 Caddy(推荐)
Caddy把反向代理和 tls 配置简化到了极致,让你无需写 Nginx 那么复杂的配置,也无需关心证书生成、配置和续期。
安装以 Ubuntu 为例,仅需几条命令:
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
注意:上面的命令安装完成后会自动注册为系统服务并启动,它默认也是监听 80 端,如果你已经启动了 Nginx 那么 Caddy 就会启动失败。
安装完后默认的配置文件在/etc/caddy/Caddyfile
,内容如下:
:80 {
root * /usr/share/caddy
file_server
}
这表示 Caddy 在 80 端口监听/usr/share/caddy
目录下的文件,并作为静态文件服务。
我们修改配置文件如下:
dev.lan {
tls internal
root * /usr/share/caddy
file_server
}
code.dev.lan {
tls internal
reverse_proxy 127.0.0.1:2333
}
这表示:
- 当访问
dev.lan
时,Caddy 会监听/usr/share/caddy
目录下的文件,并作为静态文件服务。 - 当访问
code.dev.lan
时,Caddy 会将请求转发给127.0.0.1:2333
,即反向代理。 tls internal
表示使用内置的 TLS 密钥和证书。它会自动生成、续期证书,并且自动将 http 重定向到 https。
然后重载配置sudo systemctl reload caddy
即可。
没错,就是这么简单,你不需要安装mkcert
手动生成证书,也不需要写 Nginx 那么复杂的配置,一切极简,对本地开发友好。如果你的网站在公网,域名也是公网,那么 Caddy 会自动使用Let's Encrypt获取免费证书,一样帮你自动续期。
当然,这种方式也一样需要手动安装根证书才行。查看自动生成的证书sudo ls -l /var/lib/caddy/.local/share/caddy/pki/authorities/local/
,我们把根证书复制出来sudo cp /var/lib/caddy/.local/share/caddy/pki/authorities/local/root.crt ~
,修改文件权限chmod $USER:$USER ~/root.crt
。
之后就可以分发到自己到各个终端设备安装了,但是一定要注意,不要暴露出根证书的密钥,也不要在公网上使用自签证书。
3.5 DNS解析
前面的步骤完成后,还需要让dev.lan
和*.dev.lan
能被解析到192.168.0.68
。
打开软路由系统 OpenWrt 后台,在网络
->DHCP/DNS
的常规
标签下的地址
增加记录/dev.lan/192.168.0.68
保存即可。
3.6 卸载
如果想卸载 code-server 就参考文档:
# 停止服务
sudo systemctl stop code-server@$USER
# 删除配置和数据
rm -rf ~/.local/share/code-server ~/.config/code-server
# 安装 code-server 相关命令
rm -rf ~/.local/lib/code-server-*
4. coder
Coder为远程开发提供了集中的解决方案,它可以为 VSCode、Jetbrains 系列、Corsor、Windsuf 等 IDE 提供远程开发解决方案。
其实和 vscode 远程开发的容器模式差不多,核心概念template
和workspace
。前者可以类比为dockerfile
,它当于是一个环境(workspace)模板,使用这个模板你可以创建多个环境(workspace);workspace 其实就是一个环境实例,你可以有多个环境,每个环境就是一个 docker 容器。比如你可以有一个 node 22 + python 3.11 + java 17 的环境,还可以有一个 python 3.17 + java 22 的环境,反正任意创建,随你所愿,只需要定义好模板即可。
而在每个环境中你可以设置有多少种远程 IDE,比如当你设置远程 IDE 有 vscode 时,其实就是在环境(workspace)中安装了 code-server,当然也可以同时有其他 IDE 如:Curosr、IDEA、GoLand 等。
这玩意安装起来很快,也就是一条命令的事,但是当你想要做自定义的时候,配置项较多还要熟悉模板语法,有一定的学习成本。可是你并不一定非要用这个,因此就不细说了。
总之就是,个人用户可用 code-server,企业用户可用 coder。
结语
实际体验下来,我觉得 code-server 开发简直不要太方便,某些时候甚至超越了使用 vscode 的 SSH 模式,尤其是需要写博客、跑代码的时候,随便拿一台电脑打开网页就能干,而你要做的就是把远程服务器开机。
SSH 模式也是不错的,使用于桌面版的 vscode 功能更完全,两种方式结合,让你睁开眼就编码,闭上眼就睡觉,,,根本停不下来......🎉
版权所有
版权归属:Mayee