我如何检查一个失败的`docker build`文件系统?
我正在尝试为我们的开发过程构build一个新的Docker镜像,使用cpanm
来安装一堆Perl模块作为各种项目的基础镜像。
在开发Dockerfile时, cpanm
返回一个失败代码,因为有些模块没有干净地安装。
我很确定我需要安装一些更多的东西。
我的问题是,我在哪里可以find输出中引用的/.cpanm/work
目录,以检查日志? 在一般情况下,我如何检查一个失败的docker build
命令的文件系统?
上午编辑咬了子弹,并运行我发现的发现
/var/lib/docker/aufs/diff/3afa404e[...]/.cpanm
这是可靠的,还是我最好build立一个“裸”的容器和手动运行的东西,直到我有我需要的所有东西?
每当docker成功执行Dockerfile中的一个RUN
命令时,图像文件系统中的一个新层被提交。 方便您可以使用这些图层ID作为图像来启动一个新的容器。
以下面的Dockerfile:
FROM busybox RUN echo 'foo' > /tmp/foo.txt RUN echo 'bar' >> /tmp/foo.txt
并build立它:
$ docker build -t so-2622957 . Sending build context to Docker daemon 47.62 kB Step 1/3 : FROM busybox ---> 00f017a8c2a6 Step 2/3 : RUN echo 'foo' > /tmp/foo.txt ---> Running in 4dbd01ebf27f ---> 044e1532c690 Removing intermediate container 4dbd01ebf27f Step 3/3 : RUN echo 'bar' >> /tmp/foo.txt ---> Running in 74d81cb9d2b1 ---> 5bd8172529c1 Removing intermediate container 74d81cb9d2b1 Successfully built 5bd8172529c1
您现在可以从044e1532c690
和5bd8172529c1
开始一个新的容器:
$ docker run --rm 00f017a8c2a6 cat /tmp/foo.txt cat: /tmp/foo.txt: No such file or directory $ docker run --rm 044e1532c690 cat /tmp/foo.txt foo $ docker run --rm 5bd8172529c1 cat /tmp/foo.txt foo bar
当然你可能想要启动一个shell来探索文件系统并尝试命令:
$ docker run --rm -it 044e1532c690 sh / # ls -l /tmp total 4 -rw-r--r-- 1 root root 4 Mar 9 19:09 foo.txt / # cat /tmp/foo.txt foo
当其中一个Dockerfile命令失败时,您需要做的是查找上一层的id并在从该id创build的容器中运行一个shell:
docker run --rm -it <id_last_working_layer> bash -il
一旦进入容器:
- 尝试失败的命令,并重现该问题
- 然后修复命令并testing它
- 最后用固定的命令更新你的Dockerfile
如果您确实需要在实际失败的图层中进行实验,而不是从最后一个工作层开始工作,请参阅下面的Drew的答案 。
如果您想在失败的命令之前立即检查状态,则回答最好。
但是,问题是如何检查容器本身的状态。 在我的情况下,失败的命令是一个需要几个小时的构build,所以在失败的命令之前倒回并且再次运行需要很长时间,并且不是很有帮助。
这里的解决scheme是find失败的容器:
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6934ada98de6 42e0228751b3 "/bin/sh -c './utils/" 24 minutes ago Exited (1) About a minute ago sleepy_bell
提交给一个图像:
$ docker commit 6934ada98de6 sha256:7015687976a478e0e94b60fa496d319cdf4ec847bcd612aecf869a72336e6b83
然后运行图像[如有必要,运行bash]:
$ docker run -it 7015687976a4 [bash -il]
现在,您正在查看构build失败时的状态,而不是在运行导致失败的命令之前。
在每个成功的RUN
行之后,Docker caching整个文件系统状态 。
知道:
- 检查
RUN
失败之前的最新状态,在Dockerfile(以及所有后续RUN
命令)中注释掉,然后运行docker build
和docker run
。 - 在失败的
RUN
命令之后检查状态,只需添加|| true
|| true
它迫使它成功; 然后像上面那样继续(保留所有随后的RUN
命令注释掉,运行docker build
和docker run
)
Tada,不需要混淆Docker内部或层ID,作为奖励,Docker会自动最小化需要重新完成的工作量。
我要做的是将下面的Dockerfile注释掉,包括有问题的一行。 然后你可以运行容器并手动运行docker命令,并以通常的方式查看日志。 例如,如果Dockerfile是
RUN foo RUN bar RUN baz
它会死在酒吧,我会做的
RUN foo # RUN bar # RUN baz
然后
$ docker build -t foo . $ docker run -it foo bash container# bar ...grep logs...
- 将“console.log()”调用留在producton JavaScript代码中是不是一个好主意?
- 如何写unit testing的输出?
- 如何使Chrome浏览器JavaScript控制台持续存在?
- VBA Debug.Print在哪里login?
- Visual Studio立即窗口:如何看到超过前100个项目
- 哪个是最好的Linux C / C ++debugging器(或前端到gdb)来帮助教学编程?
- Visual Studio 2010debugging不启动,F5或者点击“播放”不工作,什么都不做。 等待2-3分钟解决问题
- 在顶层函数中定义的内部函数testing和交互的最佳方法是什么?
- 如何基于对象string属性在Xcode中设置条件断点?