Linux 部署 code-server 并实现通配符端口转发
code-server
是第三方构建的vscode
网页版,在有公网服务器的情况下, 可以实现从任意浏览器访问自己的开发环境。 并且对弱网络的优化也是比较到位的,基本上感受不到延迟, 全屏之后跟微软版本的vscode
感受不出来区别。
缺点是,这毕竟是个第三方的东西,微软把一些高价值的玩意儿自己圈起来了, 典型的像msvc
调试器,pylance
语言服务器,code-server
是用不起来的。 但即使除去这些,功能已经比较惊艳了。
比较好的一种实践是,自己拿个本地的机器配置好,通过frp
把东西挂到外网去。 毕竟是开发,对后端还是有性能需求,拿 VPS 来硬撑还是太奢侈了, 拿本地机器做性能,外网主机只做转发不仅成本低,安全性也稍微好一些。
但这就必然涉及到frp
和反向代理的配置问题了,考虑到安全性又必须上https
。 此外,相当多的开发是依赖本地开服务器,本地访问浏览器的, code-serve
不在 VPS 上也不在本机的情况下,如何访问远端的非标端口服务也是个问题。 这方面code-server
和vscode
都提供了自动端口转发服务, 已经够贴心了,但如果真想要https
,还是需要配一下。
coder
vs code-server
如果去code-server
官网查,必然发现官方还提供了另一个选择叫coder
, 号称是预备给多人使用的cod-server
,很容易理解成是coder-server
高级版。
但是,试用了一下发现,这个东西还是太麻烦了。 它的主要使用模式是,通过预先配置的模板, 自动在 AWS 或者 Azure 集群这样的环境中新建开发环境。 程序登陆进公司的集群点一下就自动申请一个新的 AWS 服务器并且装好开发环境给他用, 几个小时不操作则自动回收。
虽然似乎也有在本地运行 docker 的模式,但是了几下没跑起来, 好像是跟TerraFoam
的联网有关。 感觉这个联网解决了也用处不大,个人自用不太可能随便调调开发环境就改一下 docker file. 总之,这玩意儿是个企业级的东西,个人怕是用不起来。
因此下文还是老实配置code-server
.
想搞标准化的话,有个好玩的东西叫
nixOS
.
安装和配置
本文只涉及 Linux 环境下的安装,具体环境是 Ubuntu,Windows环境当然是能装的, 并且还可以基本完美的调用msvc
和其他一些 Windows 命令行工具链。 不过比 Linux 还是要麻烦一些。想装的话可以看本站另外一篇文章。[TODO]
安装基本按官方的说明文档进行,一键安装脚本会自动检测并尽量利用系统自带的包管理器。 具体的步骤这里就不再一行一行翻译了。
注
经过考虑和尝试,放弃了 docker 安装方案。 用 docker 确实简单,但开发环境跟生产环境不一样,需要经常变更,新装包,以及储存。 在这个场景下,docker 所提供的稳健性没有意义。
按官方文档进行到最后一步,留下了一个名叫code-server@
的service
文件, 告诉你要用systemctl enable coder-server@$USER
的方式来启动。 服务名称带一个@
这个用法比较少见,意思是留下来的code-server@
实际上是一个服务模板, 对应的文件是/lib/systemd/system/code-server@.service
, 可以从中查看具体的写法。
你systemctl enable coder-server@$USER
的时候,才创建一个具体的服务, 用$USER
账号而非系统账号运行,多少会更安全一些。 $USER
则是个环境变量名,解析出来就是当前登陆的用户名。 systemctl enable coder-server@$USER
这个命令当然也可以直接写 systemctl enable coder-server@weiran
或者随便别的什么真实存在的账号。
注
这个service
文件,不满意的地方可以改,但升级的时候可能会被覆盖。记得备份。 理论上apt
在这时候是会提醒你是否覆盖还是合并的,但我貌似大概至少遇见了一次。
enable
之后记得要systemctl start coder-server@$USER
, 然后就可以在默认的8080
端口访问到网页了。 密码需要在~/.config/code-server/config.yaml
配置文件里面设置,打开就能看懂。
实际上,如果不是经常用,也可以考虑不用systemctl
服务,而是随用随开, 就直接运行code-server
命令就行了。
如果不需要折腾反向代理,仅仅是本机或者局域网用,那么下文就基本不用看了。 可以直接跳到字体相关章节。
frp 和 caddy 反向代理体系
自动端口转发体系介绍
使用frp,将实际运行code-server
这台机器的端口映射到公网的 VPS 上。 当然如果你在办公室,也可以直接访问真实机器的 IP 加端口,网速更快, 两种方案可以共存不冲突。
不过,说实话两种方案区别不大,除非是网络特别特别差的时候。 由于体验极其流畅,服务器不可能有那么低的ping
, 只能推断是在缓存方面下了比较大的功夫, 编辑内容(包括终端命令)都是先缓存在浏览器,再异步发回服务端的。
注
注意,code-server
的默认设置会有一个每秒一次的自动保存, 应该也是有网络环境方面的考量。 这个行为一般是没问题的。 但如果涉及到一些文件更改自动扫描的东西,以及磁盘写入代价太大的特殊环境 (TF 卡上的树莓派一类的),可以在配置里面更改自动保存周期。
以上跑题。
总之,如果是本地部署,或者局域网直连,或者公网直连并且提前开好了防火墙, 这个步骤是不需要的,你的服务端口是多少直接访问就行了。
code-server
的自动端口转发设计出来是给反向代理准备的。 他会提供一个特殊的路径或者域名,端口则与code-server
共享(也就是不需要额外做反向代理)。 访问这个特殊的路径的时候,请求是先发给code-server
,再转发给服务; 数据则是由code-server
先从服务那边拿过来,再呈递给浏览器。
实际操作层面上,就是检测经由自己启动的进程开了哪些本地端口, 如果发现就封装一条数据通道给客户端。 比如开发网站时通过python -m http.server
在8000
端口开了一个静态服务, 可以通过https://8000.code-serve.weiran.ink
或者 https://code-serve.weiran.ink/proxy/8000
这样的形式访问。
自动端口转发是默认打开的,在不做任何配置的情况下,默认是通过 https://code-serve.weiran.ink/proxy/8000
这样的形式访问。 这种情况的下,简单的静态网页能用,但复杂一些的站点会有路径混乱的问题, 尤其是浏览器端的javascript
会往服务端回传 url 的时候。 最好还是花点功夫配置成https://8000.code-serve.weiran.ink
这样的形式。
具体的方法是,更改/lib/systemd/system/code-server@.service
文件, 将原来的:
ExecStart=/usr/bin/code-server
改成:
ExecStart=/usr/bin/code-server --proxy-domain code-serve.weiran.ink
这样的格式。
这样,code-serve
在自己的服务配置中会检查指向8000.code-serve.weiran.ink
这样的域名,有匹配的数字端口就转发给自己的8000
端口, 算是用更改主机名的方式解决了跨内网远程访问的问题。
如果放心用http
而非https
,那么配置已经完成了。
如果用自签名证书,可以自行折腾,下面的也不用看了。
不过,这年头用caddy的自动签名可能比折腾自签名还简单点,我们可以接着看。
caddy 按需 tls 证书代替泛域名证书
前面已经说过自动端口转发,效果就是你写完代码在网页版code-server
的终端里面 开一个比如说8080
端口的服务,可以用8080.dev.xxx.com
这样的方式去访问。
一般如果谨慎一些的话,还是希望用https
方式去访问,避免隔墙有耳。 这方面最方面的是caddy,用一个反向代理就可以。 但caddy的后端仍然是lets encrypt
,对证书的申请是有限制的:
- 泛域名证书的申请和刷新都必须用DNS验证;
- 单主机证书申请的数量不限,但限制速度;
由于需要三个月刷新,不想每次折腾的话, 就必须折腾DNS服务商插件,让caddy自动进行DNS解析验证。 而国内服务商在这方面的支持是比较差的,这个不意外。
所以,我选择的方法是让caddy每次收到新的请求时,自动试试申请一个单主机证书。 反正常用的端口其实就那几个,不可能突然要开几十个端口拿来测试。
caddy 配置
TODO
DNS 解析
TODO
关于字体和 zsh
只有一条提示:
重要
字体应当装到运行浏览器那个机器上!
所以,衍生出来的问题就是,移动设备上的浏览器似乎都不太能自定义字体。
字体问题还是要忍一忍啊。谁知道能够自己安装字体的浏览器? 或者加一层wrapper给浏览器加载字体?