【问题标题】:Docker build leaves intemediate imagesDocker 构建留下中间图像
【发布时间】:2019-02-19 06:05:07
【问题描述】:

我想在自己的 composer: Docker 版本 18.06.1-ce 的最新镜像上构建,我使用这个脚本来做:

#!/bin/sh

wget -O Dockerfile https://raw.githubusercontent.com/composer/docker/edf4f0abf50da5d967408849434b9053a195b65f/1.7/Dockerfile
wget -O docker-entrypoint.sh https://raw.githubusercontent.com/composer/docker/master/1.7/docker-entrypoint.sh
chmod +x docker-entrypoint.sh
docker build -t mycomposer:latest .

但除了创建的图像

我的作曲家:最新的

我最终得到了大约 10 张图片 none:none。

docker image prune

不能解决问题。

如何从composer github这里的文件中构建 composer:latest 图像而不留下这些中间图像?

我想手动而不是使用命令 FROM,因为这是我使用 Dockerfile 作为模板并在我想要的地方添加、删除命令的第一步。但第一步是从本地 Docker 文件中获取映像构建,而不是使用 FROM 命令。我不想使用 FROM 命令,因为它意味着使用 Dockerfile 中的所有命令,我只想将其中的一些命令作为我的自定义 Dockerfile 的起点,并编辑其他一些命令,我​​将从这些命令中构建我自己的图像。

目前我设法使用本地 Dockerfile 构建镜像,但有很多不必要的镜像 none:none

而不是这样的存储库:

构建后只有一个图像。上图中单张图片来自命令:

docker pull 作曲家:最新

但这会拉取作曲家映像,而不是从我的本地 Dockerfile 构建它,因此它不会满足要求。

但是为什么在命令 pull 之后只有一个图像,而在从同一个 Dockerfile 构建后的几个图像作为 pull 需要(我假设)以及如何摆脱这些 none:none 图像?

【问题讨论】:

  • 您看到这些“none:none”图像的具体情况如何?你在运行什么具体的命令?
  • 编辑帖子并添加屏幕转储以显示所需/实际结果

标签: php image docker build composer-php


【解决方案1】:

图像是构建缓存。它们允许 docker 显着加快未来构建相同图像的速度。它们的实际磁盘使用量接近 0,因为这些层在图像之间共享,唯一的影响是一些 json 元数据和目录。构建另一个镜像并取消标记之前构建的镜像后,修剪将删除未使用的悬空镜像。

【讨论】:

  • 是有道理的,即使我查看上图所示的 docker 图像存储库,其中有很多 none:none 图像在最底部有 php:7-alpine3.7 composer:latest 图像构建自,但是如何准确地摆脱这些中间图像(或层)?你有什么命令吗?
  • 如果删除图层,则会破坏最终图像。您删除这些中间图像的目标是什么?是需要去掉那几kb的元数据,还是想防止下次构建使用缓存?
  • 我正在查看拉取的图像(不是构建),但没有看到任何中间层。我虽然在本地构建图像会提供相同的效果 - 只有一个没有任何中间层的图像,但据我所知,如果我在本地构建图像,我只是将这些层作为我想要的最终图像的必须构建块放入存储库,并且我不能选择不拥有它们 - 对吗?
  • 我仍然不明白您删除这些中间图像的目的。您希望通过删除它们来实现什么?
  • 只是不想在 docker 镜像列表中弄得一团糟,但如果它们是镜像构建的一部分并且我无法删除它们,我可以忍受。我的印象是,构建映像应该只得到一个类似于dokcer pull 命令的最终映像,该命令不会在 docker 中创建任何中间层,而只是将您拉取的映像放在那里。如果你拉一个图像,你只会在 docker 图像列表中得到那个图像,我认为构建会从本地 Dockerfile 做同样的事情。
【解决方案2】:

我的方法是从 Dockerfile 构建一个镜像:

从 github 克隆 repo。

git clone https://github.com/composer/docker.git .
cd 1.7 
docker build -t mycomposer:latest .

就是这样。

【讨论】:

  • 它构建图像。你错过了点,应该在第一行 git clone https://github.com/composer/docker.git . 但即使我设法以这种方式构建 docker 映像,它也不能解决存储库中遗留的中间映像的问题
  • @Jimmix 在克隆存储库时,您不需要点。您只需要在构建映像时使用点,这意味着您使用本地目录中的 Dockerfile。
  • 事情是关于第二行cd 1.7。当您执行git clone 时,您首先创建的目录是存储库的名称,并且在该存储库中您有目录1.7,因此cd 1.7 行不起作用,因为您要么执行cd repo-name/1.7,要么将点放在git clone 的结尾,所以 clone 不会创建它放置所有文件的 repo 目录,而是将它们放入当前目录,cd 1.7 将起作用
  • @Jimmix 那是我的错误。我忘记将目录更改为 docker,因为我正在从 github 克隆 docker 存储库。谢谢 :) 我以前不知道点 (.) 符号。
【解决方案3】:

请参考https://docs.docker.com/engine/docker-overview/#docker-objects

Dockerfile 中的每条指令都会在映像中创建一个层。当您更改 Dockerfile 并重建映像时,仅重建那些已更改的层。与其他虚拟化相比,这就是图像如此轻量、小巧和快速的部分原因

因此docker image prune 不会删除它们。没有这些图层,您的图像将无法正常工作。

【讨论】:

    【解决方案4】:

    Docker 镜像由 layers 组成;每个都有一个组合的最终图像文件系统。这些层实际上构成了一种树,其中您可能有一个基本的 Ubuntu 层,有一个安装特定 Debian 软件包的子层,还有一个添加应用程序代码的子层,等等。这些层中的每一个实际上都可以独立地用作图像,但是您不能删除基础层图像,只要它下面还有另一个图像依赖于它。

    您正在运行docker image -a,它列出了所有图像,甚至那些仅作为基础层存在的图像。这会产生一堆“额外的”<none> <none> 图像,它们是基础层。它们是无害的,并且是必需的,并且不占用任何额外资源。一般来说,使用-a 选项并不能真正告诉您任何信息,我会跳过它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-22
      • 1970-01-01
      • 1970-01-01
      • 2020-10-06
      • 2020-05-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多