cnb.cool自定义ide

缘由

我是tui用户,工作二十年一直是用基于tui的开发工具

以前都是用vim去年以来转向了helix 但基本换汤不换

药,对于大多数今天的研发人员来说都是老工具

前一阵在某个群里看到有人介绍腾讯云提供的云原生构建

服务 域名是 cnb.cool 用微信

登录下就可以有不少免费额度,界面基本跟github类似

但是他提供了一个云原生构建和研发的功能,也就是在

你个人的仓库边上有个按钮,点击下就可以启动一个

专属子域名下的vscode web版,这是跑在容器里,且里

面已经提供这个仓库的代码

几年前我在百度量子计算所做的云ide与其功能基本差不多

但不同的是,他这个背靠大树好乘凉,免费送的资源非常

丰富,(而我那会就一个人打造,且资源还是厂内计费的)

我去研究了下文档,发现官方贴心的提供了自定义容器环境

的玩法,因此我打算动手自制一个基于web terminal的tui

研发环境,最后也确实做成了,所以我在这里记录下其间的

一些关键细节供同好参考

我的目标是

  • 抛弃官方提供的臃肿底包,使用自己喜欢的alpinelinux
  • 基于alpine安装我们喜欢的tui编辑器
  • 提供一个走web访问自己容器里terminal的服务
  • 研究官方启动机制,使得点击云构建的按钮可以打开定制的服务

实现步骤

选用自定义底包

按官方文档介绍,如果你想定制,可以在自己仓库里放置一个目录

.ide 并在里面放一个用于自定义容器的 Dockerfile 熟悉使用

docker构建镜像的人都明白怎么用,是的,他跟一般的用法没两样

只有以下需要注意

  • 构建时所在的提交目录相当于仓库根目录下,所以需要引用文件时候需要注意相对路径
  • 默认构建只提交 .ide/Dockerfile 这一个,假如需要用 CODY/ADD 类命令引用 其他文件,需要按其构建工具的语法在仓库根目录下修改 .cnb.yml 文件,在里面 声明需要引用到的文件,可以参考以下截图里高亮部分写法 声明引用文件

只要注意这俩问题,基本就是正常构建镜像即可

而且还有额外的好处

  • 构建是在腾讯提供的云环境里进行,构建时提供的cpu/ram等资源很大
  • 上游的底包拉取非常快,不需要自己去折腾梯子问题
  • 由于我是用alpinelinux这种热门底包,也不排除是官方提前拉了一些镜像
  • 无障碍上网有保障,我在构建其他一个应用时尝试过从github下载文件,没有任何问题

安装自己的tui编辑器

这一步最简单,因为就是正常在Dockerfile里写

RUN apk add --no-cache helix helix-tree-sitter-vendor

这里我安装的是自用的helix 当然你也可以安装neovim或者emacs

之类的,我也曾经尝试过zellij,都没任何问题

提供web访问服务

一开始我是使用 ttyd 这款服务的,因为他非常迷你,他是c写的

且其预编译的二进制文件没有额外依赖,下载下来就能在我的alpine

底包上用,熟悉alpine的人自然知道,这里有很大的兼容问题,是因为

采用了musl造成的

ttyd使用起来也容易,主要就注意俩个选项参数

  • -W 这个参数允许用户可以写数据到目标终端,默认没有则用户是只读的
  • --port 这个参数定制ttyd监听的端口 默认是 http协议 ssl也可以自定义

后来 为了方便夹带私货,我用了caddy,当然不是抛弃了ttyd 而是让caddy

跑在最前面,然后对特定路径重定向到ttyd的服务,这样其他路径还可以用来

干别的

对接官方加载机制

官方的加载机制就两个核心问题

  • 官方网关如何转发请求到自定义容器
  • 自定义容器镜像被启动后的入口

如何转发

这个经过我反复失败以及查看构建日志,可以推断出官方网关只是简单的

将分配的专属子域名流量转发到自定义容器的 8686 端口,目前我使用

caddy在这个端口上监听 http 服务,至于是否网关支持自定义证书的 https

服务,目前没研究,但大家可以放心,网关对外的访问都是 https的

最近这几天我反复构建了几个仓库,以及几十次的构建,可以确定是这个

端口目前尚未随机。

如何启动

这里我描述的是自己的摸索与推断,并非完整的,且并非正确的官方启动思路

按我的观察是这样的

当你点击自己仓库的云原生构建按钮以后,会出来一个页面,这里是加载启动

的界面,如果有最新的自定义构建文件在,就会触发流水线去构建你自定义的

镜像待用,在等待的时候,该页面背景里的终端显示是真实的输出

如果你的自定义镜像构建失败,则会被启用官方默认的vscode那个容器

假如成功,则构建脚本会尝试跑俩命令

  • 第一个是 code-server -v 其输出我不知道是否需要对比,因此在 我的容器里,我有一个假的同名脚本,对于 -v 选项的调用会输出 与官方一模一样的版本字符串
  • 第二个是 code-server -xxx -yyy 这类真实的启动命令,我的同名 脚本会启动 s6-svscan /root/service 这是一个用来在容器里管理 多个服务的简单工具,需要安装 s6 这个包以后才能用,同时 /root/service 这个目录下需要有很多子目录,每一个会被当作一个服务项,只要有 可执行权限的 run 文件,就会被自动执行 同时是前台执行 而没有 daemonize,因此我将这个视作docker镜像的entrypoint.sh之类的入口

如果不出意外,做到以上步骤,自定义的容器就启动成功了,这里展示下

我的 正常工作

但其实官方还有后续动作,只不过由于我的目的已经达成,所以我就没有

继续研究了,欢迎有兴趣的朋友继续研究后续过程并作补充说明

启动后

这里需要提醒一个事,通过观察后续的构建日志,我可以看到,官方工具

会在自定义容器运行期间尝试杀死他,但会因为还有活动的网络链接而被

阻止,因此,并不需要特定的保活接口调用,只要确保你的web服务有类似

keepalive那种定期发心跳的功能就行,这是用于维持网络活动,而ttyd

直接自带了,因此无需任何操作。

后续应用

我已经将我的研究直接放在了cnb.cool的仓库里 访问地址 https://cnb.cool/geek42.info/test

感兴趣的可以克隆下来修改使用

这里后续的应用并不必拘泥于只是研发工具替换,完全可以使用提供的资源

提供各种服务 例如

  • 安装基于http协议的梯子工具,并用caddy分流,这样日常用来拖docker镜像和github就方便了
  • 安装短时的web应用,语音/视频会议,临时发送文件/paste , 临时对战游戏, 临时信号服务器

Comments !

blogroll

social