docker 小试

前文有说,因为 MinDoc 的调试/测试需要,搭建了个 docker 环境,在里面把 go、git 安装妥当,来开展工作。

实践中有个问题,操作起来觉得略显麻烦了些。源代码在宿主和容器里都有,在宿主里可以使用 Visual Studio Code 这样工具进行编辑,然后想办法同步到容器里进行编译运行。可是如果在测试过程中有一些小修小改都要这样搞的话,效率未免就太低了。于是就出现了直接在容器中使用 nano 之类的编辑器快速进行修改、编译的情况。这样告一段落之后,又需要把调试过的代码同步出 host 里来。

网上有人支招,用 ssh 相关的工具来解决,感觉重了些。后来发现 docker 有机制可以把 host 的目录加载到容器里,深得我心。详加考察后又略感沮丧,原来这个步骤要在容器创建时指定,一旦创建,在 start 的环节是无法补充执行的。三太爷作为:
资深三晋京飘、
重度拖延症患者、
极端强迫症患者、
前 C/C++ 程序员、
现 Android/Go/JavaScript/Objective-C/PHP/Python/Shell 业余程序员、
团队首席文档师、
精神黑客,这最后的一个头衔决定了要给容器做个小小的手术。

实用最朴素的技术思维来思考这个问题,这样的映射关系显然应该存储在容器自身的某个配置项里面。要想一睹真容,首先要创建一个具有此特性的容器。于是采用 docker create -v /home/dandy/Workspaces/code/go/src/:/root/playground/src –name dc_mindoc ubuntu 命令创建一个名为 dc_mindoc 的基于 Ubuntu 映像的容器。

做了一下功课,知道 docker 的大本营驻扎在 /var/lib/docker 路径下,只是要访问的话是需要 root 权限的。进去其中的 container 目录,根据创建时间应该立刻就能找到刚刚创建的容器所处的子目录,当然,你要能记得容器的 ID 那就可以直接杀入了。里面有五六个文件,两个 json 文件,一个 conf 文件看起来就很对眼。经过实际检测就会发现,resolv.conf 文件主要是网络域名解析相关的内容,暂时放过它。两个 json 文件一个名为 config.v2.json,一个名为 hostconfig.json,出于直觉,优先查看了后者。结果一打开发现,文件的第一个配置——名为 Binds 的数组——里面就放着目录的映射关系。到 MinDoc 容器的目录下做了相应修改,启动后发现无效。返回来接着检查 config.v2.json,果然又有发现,其中有个叫 MountPoints 的域,是这一映射的详细配置信息。于是又到 MinDoc 容器中照猫画虎,还是不行。后来想到也许是因为容器中的加载点没有预备妥当的缘故(因为想到了 mount 命令的实际情形),又手动到容器中创建了目标目录,还是不行。这三次失败的结果,除了容器中并未出现预期的目录被成功映射之外,还同时伴随有对于 json 文件的修改丢失的现象。

这下就迷茫了,一度开始怀疑自己的技术敏感度了。从单位回到家后到 GitHub 一直追踪 docker-cli 和 docker-ce 的源代码,也没看出个所以然来,后来实在是太晚了,凌晨两点半,而且白天还要上班,只好悻悻中止,上床睡觉,连最狠的准备都盘算过了,大不了下载 docker 源码,自己编译跟踪。

白天上班后,反省了一下冲动。认为当务之急还是搞定 MinDoc 想做的功能,而不是和 docker 较劲。于是又想出个笨招来,在终端下切入 root 身份,给 docker 里的目标目录在宿主里创建了个软链接,把 Beyond Compare 打开,左侧是 host 里的源代码目录,右侧是 container 里的源代码目录,用 VSC 修改之后从左侧同步到右侧,然后再到 docker 里编译运行。

编辑,保存。编译,运行。嗬,真有效果。一想,不对呀,我并没有把 host 里的源代码同步到 container 里面呀,见鬼了?一检查,还真是见鬼了。src 目录好端端地映射成功在那儿了!

目前正在享用着这个成果。为什么成功,并没有再次详细测试,但我老人家有十分把握,这个操作在必要时是可以成功复现的。如果要想象一下具体原因的话,个人认为是因为重启了一下电脑,docker 的 service 完全重新开始而引发的。也就是说,如果 docker 的 service 一直在运行状态的话,为一个容器(哪怕它已经 stop)增加目录映射是不能立刻生效的。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注