其实上篇已经详细介绍了如何从 alinode 官方镜像中提取 Dockerfile 的完整过程。
但在提取的时候,我写了个工具,方便以后使用,既然写了,就分享下。
从镜像中提取 Dockerfile
其实这个需求不应该存在,他是个不合理的需求。
没有 Dockerfile 的镜像,我们不用才对,为什么要去提取他的 Dockerfile 呢?
为了学(折)习(腾)。。
因为某些不可抗拒的原因,人家没给 Dockerfile,但你又非常想用他的镜像,然而严谨的你,不放心用一个黑盒在线上跑,那怎么办呢?
找他们要?不一定给。下班堵他们门口,逼他们给?不一定打得过他们。把所有想要配置的人集合起来,应该可以打的过。
这里说的就是 alinode 官网镜像,指名道姓说,没啥不好意思的。
alinode 年初免费后,我就直接接入用了,确实省了我不少麻烦,年中的时候上了 docker,但官网镜像太大,于是自己封装了个镜像,跑着还算稳定。
这些天百谷歌度了一大圈,也学了点姿势,也成功提取了 alinode 官网镜像的 Dockerfile,也没看到什么秘密啊,完全可以直接公布出来。
详细的提取过程上一篇介绍了,这里说 node 提取,并格式化最终结果。
写成 node 工具
其实工具有现成的,CenturyLinkLabs/dockerfile-from-image。
1 | $ docker run -v /var/run/docker.sock:/var/run/docker.sock \ |
OJB,,,报错。。。
在 issue 中看到有人 fork 并更新了代码,但依然报错,找到个 py 重写的,但没镜像,只有 dockerfile,我本地编译测试可用,但麻烦。
于是乎自称 “造轮之王” 的我就用 node 重写了个,并封装了 docker 镜像,你用 docker 或用 npx 都可以,非常爽。
项目在这个 52cik/dockerfile-from-image。
直接看下源码核心部分。
1 | const Docker = require('dockerode'); |
dockerode
是个 node 下调用 docker api 的模块。
这里几乎只用了 history
方法,因为确实就够了。
如果没有 #(nop)
层,那就是命令行,需要镜像格式化。
这里分两种情况,一种是空格党,一种是 tab 党。
最终得到格式化后的结果。
是不是感觉简单的一逼。
但 FROM
是自身,而不是他依赖的镜像,因为无法得知依赖的镜像是什么。
不过这块可以优化,我已经简单分析了各个基础镜像的版本信息,可以得到底层镜像。
这种 node:8
, buildpack-deps:jessie
二次封装的镜像,我没办法解析,
但可以解析出底层镜像,如 node:8
-> debian:8.11
, node:8-alpine
-> alpine:3.8.1
这样得到具体版本。
这个功能坐等我有空的时候加上吧,目前手动操作下也可以得到的。
1 | $ docker run --rm node:8-alpine cat /etc/os-release |
多详细,而且简单方便。
1 | $ docker run --rm node:8 cat /etc/os-release |
适配下不同镜像获取具体版本信息即可。
使用方法
因为有 npm 模块和 docker 镜像两种,所以使用方法也是两种。
1 | $ npx dockerfile-from-image nginx:alpine > Dockerfile # 输出到文件 |
npx 真香。
小结
这是一篇水文,总结加推广为主,因为详细的提取流程,上一篇已经介绍了,这里只是写成了代码。
唯一不一样的只是加了正则,格式化了输出结果,看起来跟源配置很接近,更加容易阅读。