我使用docker构建一个Web应用程序(特别是Rails应用程序)。
在这种情况下,每个版本都用git SHA值标记,:latest
标记指向最新的SHA值(例如4bfcf8d
)。
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
feeder_web 4bfcf8d c2f766746901 About a minute ago 1.61GB
feeder_web latest c2f766746901 About a minute ago 1.61GB
feeder_web c14c3e6 4cb983fbf407 13 minutes ago 1.61GB
feeder_web cc1ecd9 3923b2c0c77f 18 minutes ago 1.61GB
每个版本的区别仅在于应用程序的前端有一些次要副本,但除此之外,它们基本上是相同的。
每个列出的容量为1.61GB。如果仅在Web应用程序中更改几行,每个构建真的需要额外的1.61GB吗?如果是这样,我是否应该积极清除旧版本?
答案 0 :(得分:3)
每个版本的区别仅在于应用程序的前端有一些次要副本,但除此之外,它们基本上是相同的。每个列出的都是1.61GB。如果仅在Web应用程序中更改几行,每个构建真的需要额外的1.61GB吗?
您是否可以从层缓存中受益,很大程度上取决于您编写Dockerfile的方式。
例如,如果您写
FROM debian
COPY ./code /code
RUN apt-get update && all that jazz ... ...
...
,然后您更改该./code
的一个iota,整个层将被扔掉,其后的每一层都被扔掉。 Docker必须重新运行(并重新存储)它们的层,每次构建时还要再创建数百个兆层。但是如果你跑
FROM debian
RUN apt-get song and dance my-system deps && clean up after myself
MKDIR /code
COPY ./code/requirements /code/requirements
RUN pip or gem thingy
COPY /code/
...
现在,您不必每次都安装要求。因此,您的大部分环境(系统和语言库)都不需要更改。您只需要空间来存储以./code复制的内容,在这种情况下,此后的空间通常仍为0.1 gig左右。
社区倾向于吹捧图像中的层的最小化,并且只要具有相同寿命和依赖关系的步骤(apt-get install / cleanup)就有意义。但这实际上与效率背道而驰,如果您可以充分利用缓存。例如,如果您需要更改gem文件,则可能不需要更改所有系统库,因此除非您想要更新较低的层,否则无需重建该映像。如果您不必每次都安装libffi-dev或其他任何东西,这也会大大增加构建时间。
可能,要减小最终图像尺寸,您可以做的最大事情就是使用多阶段构建。 Python和Ruby容器通常最终会引入复杂的构建时间依赖性,然后将其保留在最终映像中。从最终映像中删除它们也是潜在的安全优势,至少在CVE暴露方面至少具有安全开销。因此,如果还没有,请查找多阶段构建,并花一个小时看看从最终映像中获取一些构建时间依赖性是否相当容易。全面披露:目前,我不确定这些构建阶段是否已自动清理。
如果是这样,我应该积极清除旧版本吗?
由于磁盘空间从根本上来说是有限的资源,因此唯一的问题是如何通过增加硬盘空间来积极性以及在多大程度上减轻磁盘空间。
也不要忘记清理旧容器。我试图尽可能地养成docker run --rm
的习惯,但是在不可避免地养成它们之后,我仍然发现自己正在修剪它们。
答案 1 :(得分:1)
如果一个版本需要1.6G,那么只需更改几行就不会更改大小。
如果您不再打算使用它们,我建议您清除旧版本。我经常执行docker system prune -a
来删除未使用的数据(图像,容器,卷等)。
答案 2 :(得分:-1)
每个版本都是一个完整的容器,而不仅仅是旧容器之上的一层。换句话说,如果您更新映像4次并重建,则您正在运行的应用程序有4个完整副本。除了您在每个版本之间进行的增量更改之外,每个彼此都非常相似,因为它们彼此之间非常相似。
在这种情况下,我认为没有任何理由不清除旧容器。他们显然正在占用大量空间。据推测,您之所以对它们进行更新是有原因的,因此,除非继续使用/测试您的应用的旧版本,并且由于该原因而需要保留它,否则至少定期清除它们可能很有意义。这是假设您在开发环境(即您的个人/工作机器)中完成所有这些操作,并且使旧版本处于休眠状态不会带来安全风险,因为它们没有主动连接到外部服务。如果这些文件在某个地方的实时服务器上运行,请在不再使用这些旧文件时将其丢弃,以免不必要地在生产服务器上暴露任何额外的攻击面。