---
url: /article/7uov7swb/index.md
---
## 前言

作为一个软件开发者，在了解了远程开发的优势后就知道它多么香。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](https://www.trae.com.cn/) 是 [Trae](https://www.trae.ai/) 的国内版本，它的功能和 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](/article/hfgdbcz2/)，可以选择最新的系统版本下载安装。如果想使用 WSL 也可以看这个[WSL2使用](/article/ryxmiytl/)。

### 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`文件，内容如下：

```ini title="config" :no-line-numbers
# 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. 远程开发

在远程机上配置好各种[开发环境](/notes/vej2ba8o/)，然后可以正常开发了。

## 2. vscode 远程开发

### 2.1 几种远程方式的区别

仔细了解过 vsode [远程开发](https://vscode.js.cn/docs/remote/remote-overview)后才发现它有多强大，其他衍生品的远程开发功能都是阉割版的。\
vscode 的远程开发有 5 中方式：

1. [SSH](https://vscode.js.cn/docs/remote/ssh-tutorial)：在远程 Linux 主机中运行 vscode 服务器，依赖 SSH；
2. [WSL](https://vscode.js.cn/docs/remote/wsl-tutorial)：在远程 Windows 主机的 Linux子系统(WSL) 中运行 vscode 服务器，依赖 SSH；
3. [Container](https://vscode.js.cn/docs/devcontainers/tutorial)：在远程 Docker 容器中运行 vscode 服务器；
4. [Tunnel](https://vscode.js.cn/docs/remote/tunnels)：在远程 Linux 或 WSL 中运行 vscode 服务器，不依赖 SSH；
5. [Codespaces](https://docs.github.com/github/developing-online-with-codespaces/using-codespaces-in-visual-studio-code)：在 GitHub 提供的 Codespaces 中运行 vscode 服务器；

> 那么，用那种方式好呢？

这就要分情况了：

* 正常情况下最推荐的方式是 SSH/WSL，一个高性能远程主机搭配普通配置的笔记本电脑，让你移动开发也能流畅丝滑。不过有两个限制：如果主机在内网需要解决内网穿透问问题、移动端电脑要能安装 vscode 和支持 SSH 协议。
* 其次就是 Tunnel(隧道)，它需要走 GitHub 或者 Microsoft 认证，所以你至少得有任一账号，并且隧道模式是经过微软的专有网络，所以即使远程主机在内网也没关系，好处就是：不需要内网穿透 、也不需要SSH，这意味着你可以通过[网页端的 vscode](https://vscode.dev)也能连接到远程开发，iPad 也能成为生产力。不过缺点就是因为要经过微软的网络，即使你本地和远程机处在同一内网下，也会在外网绕一圈，实测延迟挺高的。跑跑简单的工程或者脚本问题不大，太大的项目就不建议这么做了。
* 至于容器中开发，这一般是有特殊需求的，比如：需要同时运行多个服务端，但又需要相互隔离。这就非常有用了，通常用在需要快速的验证或者复现某个环境时。
* Codespaces 这个因为要付费，虽然有免费额度，但是长期开发的话那点临时额度根本不够用，如果临时需要启用一些还是可以的。免费的不能作为生产力，付费的就另说了。

### 2.2. 隧道模式

这里重点说一下隧道模式(Tunnel)，某些情况下还是挺有用的，比如出门在外手头上没有电脑，需要紧急处理/验证一些代码的时候，此时任何一个可以打开浏览器上网的设备都可以拿来用。

一般当你安装了任一种桌面版的 vscode 都自带了 Tunnel，打开方式点击左下角的头像`打开远程隧道访问`，有两个选项：`启用此会话`、`作为服务安装`。前者是临时启动隧道服务，下次打开 vscode 不会自动开启隧道；后者是每次打开 vscode 都会自动启动隧道。但无论哪种都是让你当前这个设备作为 vscode 服务端的。

可远程主机是 Linux 服务器，没有界面，装不了桌面版，此时就可以单独安装[CLI](https://code.visualstudio.com/Download)工具了。安装方式参考官方文档，这里不再赘述。下载下来是一个压缩包，解压后就只有一个`code`可执行文件，可以放在任意位置，运行`code tunnel`就可以启动隧道，查看[文档](https://vscode.js.cn/docs/editor/command-line#_create-remote-tunnel)探索更多使用方式。

> [如何确保隧道保持运行](https://vscode.js.cn/docs/remote/tunnels#_how-can-i-ensure-i-keep-my-tunnel-running)

一开始我想把它注册成为服务\[+service]，使之可以开机自启，能用服务启动/关闭/查看状态/查看日志等。但仔细想了想，其实完全没有必要每次都开机自启，因为绝大多数时候都是使用 SSH 模式，Tunnel 仅仅是应急，应该需要的时候启动即可。而为了能够便捷使用可以用脚本管理：
\[+service]:

安装服务：`code tunnel service install`

卸载服务：`code tunnel service uninstall`

探索更多：`code tunnel --help`

```bash title="tunnel" :collapsed-lines=5
#!/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`就又要鉴权了，所以最好确定好位置后再登录，如果移动了位置，一定要注意再前台执行一次，然后登录。

**官方提示**：

* [隧道限制](https://vscode.js.cn/docs/remote/tunnels#_are-there-usage-limits-for-the-tunneling-service): 为避免滥用，一个账号最多只能开启 5 个隧道，超过数量后，最早未使用的隧道将自动被移除。
* [访问限制](https://vscode.js.cn/docs/remote/tunnels#_can-multiple-users-or-clients-access-the-same-remote-instance-simultaneously): 不能多个用户或客户端同时访问同一远程示例，服务器实例设计为一次只能由一个用户或客户端访问。

## 3. code-server

上面 vscode 的隧道模式基本上是能用了，只是不好用，因为延迟太高了，要是不通外网还用不了。在电脑浏览器上打开它是没什么问题，但是在我的 iPad 的上打开就之中连不上隧道，又折腾了良久未能解决，偶然间让我发现了 [code-server](https://github.com/coder/code-server)。

这是一个运行在 web 上的 vscode 开源项目，它是在 vscode 开源版的基础上做了补丁，使之更适合自托管。\
使用上基本和 vscode 隧道模式一致，但因为它和微软无关，所以网络上是直连的，使用的是 Websocket 协议，延迟相当低，实际开发体验和 vscode SSH 模式并无二致。

### 3.1 安装

直接参考[官方文档](https://coder.com/docs/code-server/install)，安装方式非常多，可以在 Linux/Macos、Windows、Node.js、Docker 等环境中部署，基本上都是一条命令完成。\
接下来以在 Linux 环境中部署为例：

```bash :no-line-numbers
# 一键安装(期间只需要输入一次 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`中，内容如下:

```yaml title="config.yaml" :no-line-numbers
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`。更多说明请看[文档](https://coder.com/docs/code-server/guide)。

### 3.2 运行

一开始先临时启动执行`code-server`即可在前台运行，按下`ctrl+c`停止。如果想让它开机自启，就注册为系统服务：

```bash :no-line-numbers
# 这将 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辅助。

不过，每次刷新页面时右下角会有个提示：

```text :no-line-numbers
code-server is being accessed in an insecure context. Web views, the clipboard, and other functionality may not work as expected.
```

这提示是浏览器的安全提示，但是每次都出现有点烦人，要想解决这个问题有两方案：

1. 直接修改浏览器设置，让它不要再提示了。
2. 配置证书，使用 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`文件就可以编辑为如下内容：

```yaml title="config.yaml" :no-line-numbers
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](https://letsencrypt.org/zh-cn/docs/)申请证书并做好自动续期，或者购买付费域名，一般都有一年有效期的免费证书，并且自动监控到期提醒，到期后申请新的免费证书即可。\
不过，我并不打算把 code-server 暴露在公网，多数时间都是在内网访问，如果出门在外也可以通过 SS 节点或者 Tailscale 穿透回内网，那么我也就不需要购买域名，证书用自签的就好了。

我们可以使用开源项目[mkcert](https://github.com/FiloSottile/mkcert)来生成自签证书，首先要安装 mkcert，以 Ubuntu 系统为例，其他系统安装方式参照[文档](https://github.com/FiloSottile/mkcert?tab=readme-ov-file#installation)。

```bash :no-line-numbers
# 先安装依赖工具
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 后，就可以生成自签证书了：

```bash :no-line-numbers
# 生成系统根证书(有效期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`:

```ini title="code-server" :no-line-numbers
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/`\[+soft-link]，重载配置`sudo nginx -s reload`或`sudo systemctl reload nginx`。
\[+soft-link]: 解除软连接`sudo unlink /etc/nginx/sites-enabled/code-server`

在 Nginx 中配置过证书就不必在 code-server 配置证书了，因此`~/.config/code-server/config.yaml`内容如下：

```yaml title="config.yaml" :no-line-numbers
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 为例：

1. 修改文件名为`rootCA.crt`，然后双击安装；
2. 点击`安装证书`->`本地计算机`->`将所有的证书都放在下列存储`->`受信任的根证书颁发机构`；
3. 重启浏览器访问`https://code.dev.lan`。

可是`*.dev.lan`这个域名的证书有效期只有 90 天，到期之后需要使用`mkcert`命令重新申请，把新证书放到之前的位置后，需要重载 Nginx 配置。\
如果手动做这个事还是挺麻烦的，你当然可以使用[certbot](https://certbot.eff.org/)\[+cerbot]来完成自动监控证书到期时间以及续期。可这还是有点麻烦，强烈推荐下面的方式。
\[+cerbot]: [开源仓库](https://github.com/certbot/certbot)。

#### 3.4.3 Caddy(推荐)

[Caddy](https://caddyserver.com/docs/)\[+caddy]把反向代理和 tls 配置简化到了极致，让你无需写 Nginx 那么复杂的配置，也无需关心证书生成、配置和续期。
\[+caddy]: [中文文档](https://dengxiaolong.com/caddy/zh/)、[开源仓库](https://github.com/caddyserver/caddy)。

安装以 Ubuntu 为例，仅需几条命令：

```bash :no-line-numbers
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`，内容如下：

```text
:80 {
    root * /usr/share/caddy
    file_server
}
```

这表示 Caddy 在 80 端口监听`/usr/share/caddy`目录下的文件，并作为静态文件服务。

我们修改配置文件如下：

```text
dev.lan {
    tls internal
    root * /usr/share/caddy
    file_server
}

code.dev.lan {
    tls internal
    reverse_proxy 127.0.0.1:2333
}
```

这表示：

1. 当访问`dev.lan`时，Caddy 会监听`/usr/share/caddy`目录下的文件，并作为静态文件服务。
2. 当访问`code.dev.lan`时，Caddy 会将请求转发给`127.0.0.1:2333`，即反向代理。
3. `tls internal`表示使用内置的 TLS 密钥和证书。它会自动生成、续期证书，并且自动将 http 重定向到 https。

然后重载配置`sudo systemctl reload caddy`即可。\
没错，就是这么简单，你不需要安装`mkcert`手动生成证书，也不需要写 Nginx 那么复杂的配置，一切极简，对本地开发友好。如果你的网站在公网，域名也是公网，那么 Caddy 会自动使用[Let's Encrypt](https://letsencrypt.org/docs/)获取免费证书，一样帮你自动续期。

当然，这种方式也一样需要手动安装根证书才行。查看自动生成的证书`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 就参考[文档](https://coder.com/docs/code-server/install#uninstall)：

```bash :no-line-numbers
# 停止服务
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](https://coder.com/)为远程开发提供了集中的解决方案，它可以为 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 功能更完全，两种方式结合，让你睁开眼就编码，闭上眼就睡觉，，，根本停不下来......🎉
