我试图为我们的开发过程构建一个新的Docker映像,使用cpanm安装一堆Perl模块作为各种项目的基本映像。
在开发Dockerfile时,cpanm返回一个失败代码,因为一些模块没有干净地安装。
我很确定我需要准备安装更多的东西。
我在哪里可以找到/。在输出中引用Cpanm /work目录,以便检查日志?在一般情况下,我如何检查一个失败的docker构建命令的文件系统?
在运行一个发现后,我发现
/var/lib/docker/aufs/diff/3afa404e[...]/.cpanm
这是可靠的吗,还是我最好构建一个“裸”容器并手动运行一些东西,直到我拥有所有我需要的东西?
如果您希望在命令失败之前立即检查状态,上面的答案是有效的。
但是,问题询问如何检查失败容器本身的状态。在我的情况下,失败的命令是一个需要几个小时的构建,所以在失败的命令之前倒回并再次运行它需要很长时间,而且没有太大帮助。
这里的解决方案是找到失败的容器:
$ 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]
现在您实际上看到的是构建失败时的状态,而不是运行导致失败的命令之前的状态。
我的解决方案是看看docker文件中的哪一步失败了,在我的情况下运行bundle安装,
把它改成
RUN bundle install || cat <path to the file containing the error>
这有双重效果,打印出失败的原因,并且这个中间步骤不会被docker构建认为是失败的。所以它不会被删除,并且可以通过以下方式进行检查:
docker run --rm -it <id_last_working_layer> bash -il
在那里,您甚至可以重新运行失败的命令并进行实时测试。
目前最新的docker-desktop,没有办法选择退出
的新Buildkit,它还不支持调试(请参考
在这个GitHub线程上的最新更新:
https://github.com/moby/buildkit/issues/1472)。
找出Dockerfile中的哪一行出错了。
添加到Dockerfile的顶部:FROM xxx作为调试
添加一个额外的目标:FROM xxx作为下一个,就在失败命令的前一行(因为你不想构建那部分)。例子:
FROM xxx as debug
RUN echo "working command"
FROM xxx as next
RUN echoo "failing command"
运行docker build -f Dockerfile——target debug——tag debug。
然后你可以调试容器:docker运行- debug /bin/sh
您可以通过按CTRL P + CTRL Q退出shell
如果你想使用docker compose build而不是docker build,可以在docker-compose中添加target: debug。Yml正在建设中。
然后通过docker撰写运行xxxYourServiceNamexxx来启动容器,并使用其中之一:
上面的第二个答案是找出如何在容器中运行shell。
或者在FROM xxx之前添加ENTRYPOINT /bin/sh作为Dockerfile中的下一行。