为什么Docker容器图像如此之大?

时间:2014-06-24 18:57:41

标签: docker

我通过Fedora中的Dockerfile创建了一个简单的图像(最初为320 MB)。

添加了Nano(这个1MB大小的小编辑器),图像大小已增加到530 MB。我已经添加了Git(30-ish MB),然后我的图像大小天空火箭到830 MB。

难道不是疯了吗?

我尝试导出和导入容器以删除历史/中间图像。这项工作最多可节省25 MB,现在我的图像大小为804 MB。我还尝试在一个RUN上运行许多命令,但我仍然获得相同的初始830MB。

我怀疑是否值得使用Docker。我的意思是,我几乎没有安装任何东西而且我打了1GB。如果我不得不添加一些严重的东西,比如数据库等,我可能会耗尽磁盘空间。

任何人都有可笑的大小图像?你是如何处理它的?

除非我的Dockerfile非常不正确?

FROM fedora:latest
MAINTAINER Me NotYou <email@dot.com>
RUN yum -y install nano
RUN yum -y install git

但很难想象这里会出现什么问题。

8 个答案:

答案 0 :(得分:101)

正如@rexposadas所说,图像包含所有图层,每层包含所安装内容的所有依赖项。同样重要的是要注意基本图像(如fedora:latest)往往非常简单。您可能会对安装的软件所依赖的数量感到惊讶。

通过向每一行添加yum -y clean all,我能够使您的安装显着缩小:

FROM fedora:latest
RUN yum -y install nano && yum -y clean all
RUN yum -y install git && yum -y clean all

在提交图层之前,为每个RUN执行此操作非常重要,否则删除操作实际上不会删除数据。也就是说,在联合/写时复制文件系统中,最后清理并不会真正减少文件系统的使用,因为实际数据已经提交给较低层。要解决这个问题,你必须清理每一层。

$ docker history bf5260c6651d
IMAGE               CREATED             CREATED BY                                      SIZE
bf5260c6651d        4 days ago          /bin/sh -c yum -y install git; yum -y clean a   260.7 MB
172743bd5d60        4 days ago          /bin/sh -c yum -y install nano; yum -y clean    12.39 MB
3f2fed40e4b0        2 weeks ago         /bin/sh -c #(nop) ADD file:cee1a4fcfcd00d18da   372.7 MB
fd241224e9cf        2 weeks ago         /bin/sh -c #(nop) MAINTAINER Lokesh Mandvekar   0 B
511136ea3c5a        12 months ago                                                       0 B

答案 1 :(得分:50)

Docker镜头不大,你只是构建大图像。

aggregate(pretest_score ~ student_id, df2, max) 图像为0B,如果可以将代码编译为静态二进制文件,则可以使用它来打包代码。例如,您可以编译Go程序和package it on top of scratch以生成小于5MB的完全可用的图像。

关键是不要使用官方Docker镜像,它们太大了。 Scratch也不是那么实用,因此我建议使用Alpine Linux作为基本映像。它大约是5MB,然后只添加你的应用程序所需的内容。这篇关于Microcontainers的帖子向您展示了如何基于Alpine构建非常小的图像。

更新:官方Docker图像现在基于alpine,因此它们现在很好用。

答案 2 :(得分:24)

Here are some more things you can do

  • 尽可能避免使用多个RUN命令。尽可能多地放入一个RUN命令(使用&&
  • 清理wget或git等不必要的工具(你只需要下载或构建内容,但不能运行你的进程)

有了这两个来自@Andy和@michau的推荐,我能够将我的nodejs图像从1.062 GB调整为542 MB。

编辑: 更重要的是: “我花了一段时间才真正了解每个Dockerfile命令创建一个带有增量的新容器。[...]如果你在后面的命令中使用rm -rf文件并不重要;它们继续存在于一些中间层容器。“ 所以现在我设法将apt-get installwgetnpm install(使用git依赖项)和apt-get remove放入单个RUN命令中,所以现在我的图像只有438 MB。

编辑29/06/17

使用Docker v17.06,Dockerfiles提供了一些新功能: 您可以在一个Dockerfile中包含多个FROM语句,并且只有来自最后FROM的内容才会出现在最终的Docker镜像中。这对缩小图像大小很有用,例如:

FROM nodejs as builder
WORKDIR /var/my-project
RUN apt-get install ruby python git openssh gcc && \
    git clone my-project . && \
    npm install

FROM nodejs
COPY --from=builder /var/my-project /var/my-project

将导致图像只包含nodejs基本图像加上来自/ var / my-project的内容 - 但没有 ruby​​,python,git,openssh和gcc!< / p>

答案 3 :(得分:18)

是的,这些尺寸很荒谬,我真的不知道为什么这么少人会注意到这一点。

我制作的Ubuntu图像实际上是最小的(与其他所谓的&#34; minimal&#34;图像不同)。它被称为textlab/ubuntu-essential,有60 MB。

FROM textlab/ubuntu-essential
RUN apt-get update && apt-get -y install nano

安装nano后,上图为82 MB。

FROM textlab/ubuntu-essential
RUN apt-get update && apt-get -y install nano git

Git有更多先决条件,因此图像变大,大约192 MB。这仍然比大多数图像的初始尺寸要小。

您还可以查看the script I wrote to make the minimal Ubuntu image for Docker。您可以将其改编为Fedora,但我不确定您能够卸载多少。

答案 4 :(得分:13)

以下对我有很大帮助:

在我的容器中移除未使用的包(例如redis 1200 mb释放)后,我已完成以下操作:

  1. docker export [containerID] -o containername.tar
  2. docker import -m&#34;在此提交消息&#34; containername.tar imagename:tag
  3. 层变平。新图像的尺寸会更小,因为我已经如上所述从容器中移除了包裹。

    这需要花费大量时间来理解这一点以及为什么我添加了我的评论。

答案 5 :(得分:6)

为了获得最佳实践,您应该执行单个RUN命令,因为 Dockerfile中的每个RUN指令都在映像中写入一个新层,每个层都需要磁盘上的额外空间。为了使数字层保持最小,任何文件操作,如安装,移动,提取,删除等,理想情况下都应在单个RUN指令下进行

FROM fedora:latest
RUN yum -y install nano git && yum -y clean all

答案 6 :(得分:4)

Docker Squash是一个非常好的解决方案。你可以在最后一步而不是在每一行中array(3) { ["key1"]=> string(6) "value1" ["key2"]=> string(6) "value2" ["key3"]=> string(6) "value3" } ,然后运行一个码头壁球来摆脱所有的层。

https://github.com/jwilder/docker-squash

答案 7 :(得分:0)

是的,层系统非常令人惊讶。 如果您有基本图像并通过执行以下操作来增加它:

# Test
#
# VERSION       1

# use the centos base image provided by dotCloud
FROM centos7/wildfly
MAINTAINER JohnDo 

# Build it with: docker build -t "centos7/test" test/

# Change user into root
USER root

# Extract weblogic
RUN rm -rf /tmp/* \
    && rm -rf /wildfly/* 

图像尺寸完全相同。这实际上意味着,你必须设法在你的RUN步骤中加入大量的提取,安装和清理魔法,使图像与安装的软件一样小。

这让生活变得更加艰难......

dockerBuild缺少RUN步骤而没有提交。