最近研究了一下如何掰开别人构建好的docker镜像,扒拉出原来的构建命令。

很多前辈都说是没法查到的,但是经过梳理发现还是有一点方法可以扒拉出来的。下面以coolq的镜像为例记录一下蒸锅过程备忘。

 为了方便,我是在群晖里安装docker测试的。下载的coolq版本是:v3.0.1的后一个版本,也就是这篇文章写的时候的最新版本latest

先拉取coolq镜像:

docker pull coolq/wine-coolq:latest
然后通过以下命令查看该镜像的构建history(该命令输出相关参数的解释参照文章:):
docker history coolq/wine-coolq:latest --format "table {{.ID}}\t{{.CreatedBy}}\t{{.Size}}" --no-trunc

将输出复制到你喜欢的文本编辑器里,比如UE。很整齐的样子对吧,我们主要要的就是CREATED BY这列内容。

docker pull na docker pull nastool/nas-tools_nginx

 

 

从下往上看。

第一行就是:/bin/sh -c #(nop) ADD file:91a750fb184711fde03c9172f41e8a907ccbb1bfb904c2c3f4ef595fcddbc3a9 in / 

看起来他往镜像里添加了一个文件,可是是什么不知道,文件名已经被docker build的时候加密了。

好吧,我们就搜索一下这个:91a750fb184711fde03c9172f41e8a907ccbb1bfb904c2c3f4ef595fcddbc3a9 

竟然有收获:https://microbadger.com/images/x11vnc/desktop

这里有个x11vnc/desktop的镜像里也包含了这个构建,看第一部分,竟然是ubuntu的镜像,版本号:bionic-20200219。

docker pull na docker pull nastool/nas-tools_docker pull na_02

 

 

红框里的内容是不是跟咱们history的最后五行几乎一毛一样滴?!

docker pull na docker pull nastool/nas-tools_git_03

 

这说明最后五行就是ubuntu镜像构建时候的命令,我们就不管了。

从倒数第六行开始,我们写一个Dockerfile,试试能否构建出一个coolq镜像就行了。好戏开始了。咱们继续,骚年~

用putty连接群晖。

登录后 sudo -i,输入密码,切换到超级root。

mkdir coolq
cd coolq
touch Dockerfile
vi Dockerfile
先写下初始的几行:
#coolWeChat
 FROM ubuntu:bionic-20200219
 MAINTAINER robin lee bingor.lee@outlook.com
 接下来,看看倒数第六行的CREATED BY是什么内容:/bin/sh -c #(nop)  ENV LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 S6_BEHAVIOUR_IF_STAGE2_FAILS=2 S6_CMD_ARG0=/sbin/entrypoint.sh VNC_GEOMETRY=800x600 VNC_PASSWD=MAX8char USER_PASSWD= DEBIAN_FRONTEND=noninteractive                                                                           
经过仔细观察 除了 RUN 命令外都会包含:/bin/sh -c #(nop)
这行其实就是:ENV LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 S6_BEHAVIOUR_IF_STAGE2_FAILS=2 S6_CMD_ARG0=/sbin/entrypoint.sh VNC_GEOMETRY=800x600 VNC_PASSWD=MAX8char USER_PASSWD= DEBIAN_FRONTEND=noninteractive
我们把他写入我们的Dockerfile
然后再继续上面一行整理一下:
RUN groupadd user && useradd -m -g user user &&     apt-get update && apt-get upgrade -y &&     apt-get install -y         git         ca-certificates wget locales         nginx sudo         xorg openbox python-numpy rxvt-unicode &&     wget -O - https://github.com/just-containers/s6-overlay/releases/download/v1.22.1.0/s6-overlay-amd64.tar.gz | tar -xzv &&     ln -s /init /init.entrypoint &&     wget -O /tmp/tigervnc.tar.gz https://bintray.com/tigervnc/stable/download_file?file_path=tigervnc-1.10.1.x86_64.tar.gz &&     tar xzf /tmp/tigervnc.tar.gz -C /tmp &&     chown root:root -R /tmp/tigervnc-1.10.1.x86_64 &&     tar c -C /tmp/tigervnc-1.10.1.x86_64 usr | tar x -C / &&     locale-gen en_US.UTF-8 &&     mkdir -p /app/src &&     git clone --depth=1 https://github.com/novnc/noVNC.git /app/src/novnc &&     git clone --depth=1 https://github.com/novnc/websockify.git /app/src/websockify &&     apt-get purge -y git wget &&     apt-get autoremove -y &&     apt-get clean &&     rm -fr /tmp/* /app/src/novnc/.git /app/src/websockify/.git /var/lib/apt/lists

再上一行又懵逼了:

/bin/sh -c #(nop) COPY dir:7b423d36789fa75f7f2877b3d321ddf56487710e47482a8122919ac4626e7938 in /

docker pull na docker pull nastool/nas-tools_docker_04

好啦,表芳!

看起来是 COPY了一个目录到镜像里,像那么回事。

我们把拉取的coolq RUN起来,再拉取一个ubuntu:bonic:20200219跑起来。进去看看。

docker pull ubuntu:bionic-20200219

对比一下两个镜像里有什么不一样。

是不是,看不出来~哈哈,我也是,有点复杂拉~~~难道没办法了?古人告诉过我们“抛转引玉”,我们现在就抛一块砖,看能否引出玉来吧。方法如下:

我们在Dockerfile里写入:

#COPY dir:7b423d36789fa75f7f2877b3d321ddf56487710e47482a8122919ac4626e7938 in /

意思是这个命令是啥不知道,先注释在这里。然后我们继续把上几行的命令写完。

EXPOSE 5901/tcp 9000/tcp 9001/tcp
 ENTRYPOINT ["/init.entrypoint"]
 CMD ["start"]


然后build一下镜像。

docker build -t coolqtest1:v1 .
是不是开始 跑码,跑码,跑马溜溜的山上,一朵溜溜的BUG 。。。。。

啰嗦半天跑完了,说成功生成一个镜像,好了,我们run下这个镜像,用群晖就比较容易,点启动。一切默认。跑起来!

丢(第二声)~~~,容器启动又停止了~~去容器日志看看,是不是报错了,哈哈~这就是我们抛出来的砖,仔细看说有个文件没找到。/sbin/entrypoint.sh

好办,我们从coolq镜像里把他拉出来。

mkdir copyfiles2
mkdir copyfiles2/sbin
 docker cp 46a5fb88f6c4:/sbin/entrypoint.sh ./copyfiles2/sbin/

注:46a5fb88f6c4是coolq起的容器的ID,可以通过docker ps查看到。

我们vi ./copyfiles2/sbin/entrypoint.sh,内容整理了一下,他要用到的脚本如下:

/bin/s6-svc -wu -T 5000 -u /var/run/s6/services/tigervnc
 /bin/s6-svc -wu -T 5000 -u /var/run/s6/services/websocketify
 /bin/s6-svc -wu -T 5000 -u /var/run/s6/services/nginx
 sudo --preserve-env -Hu user /app/vncmain.sh "$@"

这里说明一下:/bin/s6-svc这个在之前的构建里安装了s6,然后用s6来管理服务,回收僵尸进程,s6启动时,会把 /etc/services.d/下的服务都复制到 /var/run/s6/services下启动并监控,避免过多垃圾进程导致你的容器奔溃掉(如果想了解下s6可以看这里:),之前不太懂,想要改下/var/run/s6/services/tigervnc/run脚本,怎么改都不行,后来才知道要去/etc/services.d/下去改,哎,我踩坑,你受益啊~

好,既然知道这个脚本启动的服务都是从/etc/services.d/下复制的,那我们去我们构建的镜像起的容器里去看看,是不是没有这些服务?愣着干嘛,拉出来啊~

mkdir copyfiles2/etc
mkdir copyfiles2/etc/services.d
docker cp 0d1502a2afa0:/etc/services.d ./copyfiles2/etc/
mkdir copyfiles2/app
docker cp 0d1502a2afa0:/app/vncmain.sh ./copyfiles2/app

注:这里有个知识点(坑),46a5fb88f6c4:/etc/services.d 如果最后没有/就是把这个services.d目录名复制到后面的etc下,如果有/就是复制下面的所有文件还有文件夹(参考:https://www.it1352.com/647399.html

坑2:如果报"docker cp" requires exactly 2 arguments.那就看看  后面的路径参数之间是不是不是半角的空格,删除空格再加一个!

好了,文件有了,我们继续完善我们的Dockerfile

在#COPY dir:7b423d36789fa75f7f2877b3d321ddf56487710e47482a8122919ac4626e7938 in /下添加
 WORKDIR ./
 COPY copyfiles2 /

注:知识点这个COPY copyfiles2 /如果直接写,build到时候,你会收到报错COPY failed: stat /volume1/@docker/tmp/docker-builder239052814/copyfile2: no such file or directory

WORKDIR ./是告诉docker build运行下一条命令的工作目录是当前目录,不然他就会懵逼说找不到,找不到你妹啊~不愧是Do坑儿啊~丢~~~你懂的二声。

好了,是不是迫不及待的想要了~~~~打住~想要build一下了。

docker build -t coolqtest1:v4 .

我们build一个tag为v4的新版本吧,上面我们每次build都会用不通的tag。好看到有啥不同,搞完了,到时候记得docker rmi删除掉多余的镜像哈。

等我啰嗦完,他也Biu~完了,我们RUN一下。

是不是还是容器退出了?!表芳~~~看看日志~是不是说启动80端口时端口被占用了?说明原作者还修改nginx.conf的配置文件。

把他也撸出来~

mkdir copyfiles2/etc/nginx
docker cp 0d1502a2afa0:/etc/nginx/nginx.conf ./copyfiles2/etc/nginx/

继续Biu~~~Run,哈哈,是不是容器不会退出了,浏览器访问:http://ip:9000是不是可以看到noVNC的界面了?!

别鸡动~~进不去的~~~

好吧,继续长征~

继续往上看build的history是不是又有一个:

COPY dir:4f1dc1b5cc5c6e51966462d288d9524e613a6a4f26b780d54fc81d2b0fd731ed in /

是不是心里芳的一批~~~

老办法给她备注到 Dockerfile里去:

#COPY dir:4f1dc1b5cc5c6e51966462d288d9524e613a6a4f26b780d54fc81d2b0fd731ed in /

然后继续:

RUN chown root:root /tmp &&     chmod 1777 /tmp &&     apt-get update &&     apt-get install -y wget software-properties-common apt-transport-https &&     wget -O- -nc https://dl.winehq.org/wine-builds/winehq.key | apt-key add - &&     apt-add-repository -y https://dl.winehq.org/wine-builds/ubuntu &&     add-apt-repository -y ppa:cybermax-dexter/sdl2-backport &&     dpkg --add-architecture i386 &&     apt-get update &&     apt-get install -y         cabextract unzip python-numpy         language-pack-zh-hans tzdata fontconfig &&     apt-get install -y --no-install-recommends         fcitx fcitx-ui-classic fcitx-pinyin &&     apt-get install -y --allow-unauthenticated --install-recommends winehq-devel &&     wget -O /usr/local/bin/winetricks https://github.com/Winetricks/winetricks/raw/master/src/winetricks &&     chmod 755 /usr/local/bin/winetricks &&     wget -O /tmp/gecko.tar.gz http://dl.winehq.org/wine/wine-gecko/2.47.1/wine-gecko-2.47.1-x86.tar.bz2 &&     mkdir -p /usr/share/wine/gecko &&     tar xf /tmp/gecko.tar.gz -C /usr/share/wine/gecko &&     apt-get purge -y software-properties-common apt-transport-https &&     apt-get autoremove -y &&     apt-get clean &&     rm -rf /var/lib/apt/lists
RUN chsh -s /bin/bash user &&     su user -c 'WINEARCH=win32 /usr/bin/wine wineboot' &&     su user -c '/usr/bin/wine regedit.exe /s /tmp/coolq.reg' &&     su user -c 'wineboot' &&     echo 'quiet=on' > /etc/wgetrc &&     su user -c '/usr/local/bin/winetricks -q win7' &&     su user -c '/usr/local/bin/winetricks -q /tmp/winhttp_2ksp4.verb' &&     su user -c '/usr/local/bin/winetricks -q msscript' &&     su user -c '/usr/local/bin/winetricks -q fontsmooth=rgb' &&     wget https://dlsec.cqp.me/docker-simsun -O /tmp/simsun.zip &&     mkdir -p /home/user/.wine/drive_c/windows/Fonts &&     unzip /tmp/simsun.zip -d /home/user/.wine/drive_c/windows/Fonts &&     mkdir -p /home/user/.fonts/ &&     ln -s /home/user/.wine/drive_c/windows/Fonts/simsun.ttc /home/user/.fonts/ &&     chown -R user:user /home/user &&     su user -c 'fc-cache -v' &&     mkdir /home/user/coolq &&     rm -rf /home/user/.cache/winetricks /tmp/* /etc/wgetrc
ENV LANG=zh_CN.UTF-8 LC_ALL=zh_CN.UTF-8 TZ=Asia/Shanghai COOLQ_URL=http://dlsec.cqp.me/cqa-tuling
VOLUME [/home/user/coolq]

保存(vi的话按esc 输入:wq回车)后,Biu~~~RUN.....

版本号v5:  docker build -t coolqtest1:v5 .

v5???到这里是不是觉得曙光就在眼前,自己也有点威武了,别飘~~嘿嘿。

这里镜像增加了1.2GB,好大啊,雅蠛蝶~~

下载也要好久~~

等呗~

构建有两个文件找不到,这个就牵扯的coolq的了,通过搜索,发现这里有:

https://github.com/kotonemoe/docker-wine-coolq-dotnet45

wget https://github.com/kotonemoe/docker-wine-coolq-dotnet45/raw/master/winhttp_2ksp4.verb

wget https://raw.githubusercontent.com/kotonemoe/docker-wine-coolq-dotnet45/master/coolq.reg

mkdir copyfiles2/tmp

mv winhttp_2ksp4.verb copyfiles2/tmp/

mv coolq.reg copyfiles2/tmp/

如果下不了,你就需要梯子。

继续构建,试试看。

现在报访问/tmp没有权限