为什么docker构建不显示任何命令输出?

来自我的Dockerfile的片段:

FROM node:12.18.0
RUN echo "hello world"
RUN psql --version

当我运行docker build .时,我看不到这两个命令的任何输出,即使它们没有被缓存。文档说docker build默认是verbose的。为什么我没有看到命令的输出?我以前见过他们。

构建时的输出:

=> [7/18] RUN echo "hello world"                         0.9s

我在建筑完成后看到的输出:

=> CACHED [6/18] RUN apt-get install postgresql -y      0.0s
=> [7/18] RUN echo "hello world"                        6.4s
=> [8/18] RUN psql --version                           17.1s

Dockerfile是从基于Debian 9的node:12.18.0创建的。

Docker版本19.03.13,build 4484c46d9d。

131890 次浏览

您所显示的输出来自buildkit,它是docker附带的经典构建引擎的替代品。你可以用--progress选项来调整输出:

  --progress string         Set type of progress output (auto, plain, tty). Use plain to show container output
(default "auto")

添加--progress=plain将显示未从缓存加载的运行命令的输出。这也可以通过设置BUILDKIT_PROGRESS变量来实现:

export BUILDKIT_PROGRESS=plain

如果你正在调试一个构建,并且这些步骤已经被缓存了,在你的构建中添加--no-cache来重新运行这些步骤并重新显示输出:

docker build --progress=plain --no-cache ...

如果你不想使用buildkit,你可以通过在你的shell中导出DOCKER_BUILDKIT=0来恢复到旧的构建引擎,例如:

DOCKER_BUILDKIT=0 docker build ...

export DOCKER_BUILDKIT=0
docker build ...

只需要在build之后使用这个标志--progress=plain

例如:

docker-compose build --progress=plain <container_name>

docker build --progress=plain .

如果你不想每次都使用这个标志,那么永久地告诉docker使用这个标志,如下所示:

export BUILDKIT_PROGRESS=plain

下面是当你输入docker build --help时的官方文档。

--progress string         Set type of progress output (auto, plain, tty). Use plain to show container output (default "auto")

作为指定--progress=plain选项的另一种选择,你也可以永久禁用&;pretty&;通过在shell配置中设置这个env变量输出:

export BUILDKIT_PROGRESS=plain

在Docker 20.10中,我也不得不使用——no-cache标志。否则缓存的输出将不会显示。

docker build --progress=plain --no-cache .

做两件事

  1. 不要使用docker build .
docker build . --progress=plain
  1. 每次构建时,在RUN命令中添加随机垃圾(这会使docker误以为它以前没有见过该命令,因此它不会使用缓存版本)

例子。如果你的命令是RUN ls,则使用RUN ls && echo sdfjskdflsjdf代替(每次构建时将sdfjskdflsjdf更改为其他内容)。

为什么会这样

我尝试了其他答案,但都有问题和不完美之处。非常令人沮丧的是,Docker没有一些简单的功能,如--verbose=true

这是我最终使用的(这很可笑,但很有效)。

假设你想要看到ls命令的输出,这个不会工作docker build .

RUN ls

但是这个输出docker build --progress=plain:

RUN ls

现在再试一次,它不会打印!-这是因为docker缓存了未更改的层,所以技巧是每次通过添加一些无意义的&& echo sdfljsdfljksdfljk来改变命令,并每次改变无意义的docker build --progress=plain:

# This prints
RUN ls && echo sdfljsdfljksdfljk
# Next time you run it use a different token
RUN ls && echo sdlfkjsldfkjlskj

所以每一次,我都捣碎键盘,想出一个新的标记。Stupifying。(注意,我尝试了类似&& openssl rand -base64 12的东西来生成一个随机字符串,但docker意识到代码没有改变,这是行不通的)。

这个解决方案远不如真正的docker对打印输出到控制台的支持。