我通过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
但很难想象这里会出现什么问题。
答案 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
命令(使用&&
)有了这两个来自@Andy和@michau的推荐,我能够将我的nodejs图像从1.062 GB调整为542 MB。
编辑:
更重要的是:
“我花了一段时间才真正了解每个Dockerfile命令创建一个带有增量的新容器。[...]如果你在后面的命令中使用rm -rf文件并不重要;它们继续存在于一些中间层容器。“
所以现在我设法将apt-get install
,wget
,npm 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释放)后,我已完成以下操作:
层变平。新图像的尺寸会更小,因为我已经如上所述从容器中移除了包裹。
这需要花费大量时间来理解这一点以及为什么我添加了我的评论。
答案 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"
}
,然后运行一个码头壁球来摆脱所有的层。
答案 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步骤而没有提交。