首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何检查失败的` `docker build`的文件系统?

如何检查失败的` `docker build`的文件系统?
EN

Stack Overflow用户
提问于 2014-10-07 00:50:20
回答 8查看 133.6K关注 0票数 364

我正在尝试为我们的开发过程构建一个新的Docker镜像,使用cpanm安装一组Perl模块作为各种项目的基础镜像。

在开发Dockerfile时,由于某些模块没有干净地安装,cpanm返回了一个失败代码。

我相当确定我需要让apt安装更多的东西。

我的问题是,在哪里可以找到输出中引用的/.cpanm/work目录,以便检查日志?在一般情况下,如何检查失败的docker build命令的文件系统?

在咬紧牙关运行我发现的一个find之后,早上编辑

代码语言:javascript
复制
/var/lib/docker/aufs/diff/3afa404e[...]/.cpanm

这是可靠的吗,或者我最好构建一个“裸”容器并手动运行东西,直到我有了所有我需要的东西?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2014-10-07 02:38:36

每次docker成功地从docker文件执行RUN命令时,就会提交a new layer in the image filesystem。您可以方便地使用这些层ids作为图像来启动新的容器。

获取以下Dockerfile:

代码语言:javascript
复制
FROM busybox
RUN echo 'foo' > /tmp/foo.txt
RUN echo 'bar' >> /tmp/foo.txt

并构建它:

代码语言:javascript
复制
$ docker build -t so-26220957 .
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

您现在可以从00f017a8c2a6044e1532c6905bd8172529c1启动一个新容器

代码语言:javascript
复制
$ 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来探索文件系统并尝试命令:

代码语言:javascript
复制
$ 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创建的容器中运行一个

代码语言:javascript
复制
docker run --rm -it <id_last_working_layer> bash -il

进入容器后:

  • 尝试失败的命令,并重新生成
  • 命令,然后修复该命令并对其进行测试
  • 最后使用修复后的命令

更新Dockerfile文件

如果您确实需要在失败的实际层中进行实验,而不是从最后一个工作层开始工作,请参见Drew's answer

票数 465
EN

Stack Overflow用户

发布于 2016-02-14 09:35:33

最好的答案适用于您想要检查失败命令之前的状态的情况。

然而,问题是如何检查失败容器本身的状态。在我的情况下,失败的命令是一个需要几个小时的构建,所以在失败的命令之前倒带并再次运行它需要很长的时间,并且不是很有帮助。

这里的解决方案是找到失败的容器:

代码语言:javascript
复制
$ 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

将其提交到镜像:

代码语言:javascript
复制
$ docker commit 6934ada98de6
sha256:7015687976a478e0e94b60fa496d319cdf4ec847bcd612aecf869a72336e6b83

然后运行镜像(如果需要),运行bash

代码语言:javascript
复制
$ docker run -it 7015687976a4 [bash -il]

现在,您实际查看的是构建失败时的状态,而不是运行导致失败的命令之前的构建状态。

票数 246
EN

Stack Overflow用户

发布于 2021-03-24 04:25:42

更新的docker版本20.10及以后的更新

Linux或macOS

代码语言:javascript
复制
DOCKER_BUILDKIT=0 docker build ...

视窗

代码语言:javascript
复制
# Command line
set DOCKER_BUILDKIT=0 docker build ...
# PowerShell
$env:DOCKER_BUILDKIT=0

使用DOCKER_BUILDKIT=0 docker build ...获取旧版本中已知的中间容器散列。

在较新的版本中,Buildkit是默认激活的。建议仅将其用于调试目的。Build Kit可以使您的构建速度更快。

仅供参考: Buildkit不支持中间容器散列:https://github.com/moby/buildkit/issues/1053

感谢@David Callanan和@MegaCookie的投入。

票数 63
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26220957

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档