基于 docker 和 plan9port 搭建开发环境

2021-11-10

家里放了一个台式机做主力开发机,之前的笔记本一直还是有在用到。由于台式机装的 linux,而有时候会有些需要在 windows 下面使用的软件,就只能切回来。再比如出差了,不可能带着台式,还是要用到之前的本本的。

之前也试过把台式当服务器用,然后用笔记本连上去做开发,但是大部分时间都是在家里面,所以直接使用台式总是更舒服一些。前阵子因为疫情,我被集中隔离了。在酒店只带上了笔记本,逼着我思考,怎么样有一个更一致,更好用的开发环境。

其实这么多年,总结下来,作为开发环境,我真正需要的只有三个东西:浏览器,编辑器,终端。对于窗口管理器没什么特殊的需求,像 i3 那种平铺窗口管理器,或者是系统自带的重量桌面环境,都无所谓。反正其实我的操作习惯就是在这三者切来切去,alter + tab 足已,三者各自是独立占满的全屏。浏览器还是 chrome 为主,firefox 崩溃过几次就没再给它机会了。编辑器折腾过好多,用得最多的还是 emacs。终端是一类泛称,其实是指 linux 的平发环境,这就包括了 shell 以及常用的 linux 命令,它们都是以 terminal 那个黑框框为交互起点的。

这三者是不可相互替代的。浏览器自不用说,说说编辑器和终端。有些人觉得 all in emacs,或者是用终端模式 tmux + vi 才纯粹,但是在我这边体验下来,追求这种集成性的收益不如让他们并存。 emacs 是不能替换终端的,内置的 eshell 不咋中用,然后 term 这种也是,一旦要用到带图形的,比如 top 或者 vi,就很难受。可以用命令在 emacs 起外部终端,再去那个终端执行命令。但是如果频繁地需要切换到终端那边去执行,也就说明了 emacs 替换不了终端,还不如让终端一直在那里。 至于纯终端里面开编辑器(一般是vi)的搞法,用 tmux 类保持 session 状态,我也不太喜欢,编辑器抛弃了强大的图形能力。顶多有时候连上远程机器,不得已使用下 vim,这时 vim 占满整个终端屏幕,终端的使用就受影响了。

我自己的使用习惯,会在终端下面 cd 各种目录(带补全),执行各种命令,当需要编辑的时候,直接 e xxx,我给 emacsclient 做了 alias,直接就叫 e,这样就会在图形化的 emacs 那边打开编辑窗口,互不影响。至于项目的编译啥的,我又会从 emacs 那边切回终端,执行 make。多年习惯了,就很顺手。操作时,终端和编辑器之间共存,互不影响又需要相互跳转...

如果需要连远程开发,那么终端的重要性就更加提升了,大部分都是围绕着一个 ssh 上去的终端进行的。这种情况下如果想用 emacs,并且不是使用 terminal 的 emacs,有一个搞法是做本地起 X server,然后 ssh 转发,这样就可以 emacs 运行在远程,然后图形却是运行在本地,e 命令也是一直可以用的。从 window 连本机的虚拟机或者 docker 就可以用这种搞法,但是当延迟比较高的时候,连一个远程的 ssh 服务器那么流畅性就不太好保证了。

emacs 还有另外一个方案,是反向的操作,在本机上面起 emacs 服务,然后做 ssh 转发,然后远程那边用 emacsclient 连到 unix domain 文件,这算是另一种可选项,相比 X Server 那层的转发,对网络延迟要求会低一些。

还有第三种方案是把远程的文件 sshfs mount 到本地,然后用本地的编辑器编辑远程文件。放弃图形,ssh 上去用终端然后用 vim,我不太喜欢这种的搞法。

相对来说,在远程编辑这块,vscode 真是完暴其它方案好几条街,暴到渣渣都剩。用 remote ssh 或者 remote docker 插件,其实可以达到我想要的开发环境的效果。只是多年的使用习惯,还是更喜欢简单的和熟习的事物。

再说一说 docker。在 windows 下,我还是需要一个 linux 的开发环境的,无论 CygWin 或者是 MinGW 这种,要不在兼容性,要不在支持的范围上,始终没有直接用真实的 linux 来得舒服。所以可选项要么就 WSL2 要么就 docker。 linux 随着自己的配置和习惯,会越用越好用(跟 windows 越用越卡然后无奈重装系统形成鲜明对比),但是每次换系统时就很折腾。我现开发环境现在就有好几种情况:

  • 最常用的,直接在台式机上面开发;
  • 一种是用笔记本连上自己的台式机去做开发;
  • 另一种是笔记本上本机的 windows 系统上面,起一个 linux 开发;
  • 还有一种情况是,我笔记本装了双系统,可以重启系统后切换到 linux 去

这些环境就变得更混乱了,跟我想要的一致的开发体验不符合。如果开发环境是基于 docker 的,这些混乱情况就可以合而为一了。

docker 里面可以打包最常用的那些命令,但不需要是一个巨无霸的复杂的环境。数据和常用命令部分分离,数据用 mount 过去就行,包括个人的配置的数据,项目等。 项目的这些,数据存在多份并且不一致,并不可怕。因为反正都在 github 上面,都可以拉下来的。笔记本的数据,跟台式机的数据,都可以是不一样的,但只要配置得差不多,开发体验就一致了。个人的配置文件部分也是属于数据的。

接下来说说 plan9 的意义。只需要打包 plan9port 一个 repo,就可以得到很多的开发环境命令了。linux 太大了,命令多也就更复杂,而如果统一成 plan9,终端环境的命令就很一致。当然,如果真要用一个纯粹的 plan9 操作系统,那实用性又太低了,没法干活,所以 linux 的 plan9port 正好是这样一个平衡点。docker 就打包一个 plan9port,命令这块就齐了。甚至 shell 都不用再纠结,到底是默认的 bash,还是配置后的 zsh 亦或是 fish 之类的...直接用 plan9 的 rc!

通过 docker 打包 plan9port,一致性的终端的环境搞定了。远程开发的时候,浏览器都用本地的,不是一个问题,剩下的,是编辑器怎么处理。前面说了,emacs 这块还是做得不够完美。我想到的一个解决方案是 acme。

之前也用过一阵子的 acme,acme 是一个真正的集成开发环境,只是论终端能力,它比不了真正的终端:兼容性不行,top 甚至 less, tail -f 啥的都用不了。论编辑能力,即没有代码高亮,也没有自动补全,所有现代编辑器具备的特性,它全部没有,编辑能力是被 emacs 秒到渣渣都不剩。acme 还有一个致命的问题,是中文输入的支持。如果不能用它敲中文,那真的完全没法用呀。但是为什么要考虑它呢?因为在非本地开发这种环境下,它确实可以将终端和编辑整合成一个,而且还是具备图形能力的!

一些 work around 记录。真正需要用到兼容终端运行命令的时候,可用在 acme 里面唤出一个 st,然后在里面执行命令。需要编辑中文的时候,可以在 st 里面用 vim 搞。acme 有一个 Go 的实现,叫 edwood,我可以正好研究下它,是否能把中文编辑给支持了。默认的 acme 的 win 里面,连 git log 都看不了,需要设置 PAGER=nobs。图形方面,如果是 window 连到本机的 linux,可以在 windows 上面开 X Server。如果是 ssh 到远程,可以在本地开 devdraw,然后把远程 acme 的连接请求 forward 到本地,都不用开 X server。

好啦,看这一次我能把 acme 坚持使用多久吧!

开发环境plan9

HNS.to is a highly insecure way of browsing Handshake domains and should only be used for demo or educational purposes. Click to see preferable resolutions methods