Dockerfile:我的EXPOSE位置是否正确?

时间:2017-07-24 22:53:31

标签: docker dockerfile

我在处理opensource Dockerfile时遇到的问题时感到困惑,归结为"为什么要更改图层?" - 所以我试图通过自己的调查回答这个问题。

我很抱歉这个主题没有明确定义,但实质上它是关于docker层如何与docker-cache相关。

所以我在一个没有充分记录的领域寻找一个优雅的解释。

我对原始Dockerfile的更改将ENV分隔到不同的层,先前移动COPY,然后再显示端口。

原文(简化):

FROM ubuntu:latest
ENV HELLO world  
ENV DOCKER whale   # <-- Separate ENV into different layers
COPY source /to/container   # <-- Less prone to change, move earlier
RUN # Run stuff
EXPOSE 80          # <-- "Bake in" port later
CMD # Do stuff

我的更改:

{{1}}

推定

我的理解是,从docker-cache的角度来看, 将ENV变量分成不同的层是一个很好的做法,因为 - 如果是用户想要覆盖ENV - 只有一个ENV需要在它自己的层 内进行更改,而不是为了整个包含所有ENV的整个层而改变一个。

但是稍后添加端口EXPOSE - 感觉还不错。这是因为我已经使用Docker大约18个月了,几乎所有Docker的文档和指南都会在Dockerfile中稍后公开端口。

我也根据我的经验(并参加了DockerCon2017并参加了一些&#34;最佳实践和#34;课程)来相信这一点 应该更容易发生更改/覆盖的图层稍后放在Dockerfile 中,以更好地优化docker-cache,这样就没有那么多低级别的层变化。

问题:

我的观点是正确的(或愚蠢的)假设分离ENV层,提前移动COPY, 稍后放置EXPOSE层 是一种良好的做法,并且是对从优化Docker缓存的角度看原始Dockerfile的层?

1 个答案:

答案 0 :(得分:2)

虽然这个问题有一些很有见解的可能答案,但我会尝试跟踪来自docker's docs on this

的事实和其他事情。

Docker中图层的正确分层基本上有三个目标(大致有序):

  1. 正确性:有些事情需要合并/排序才能正确(例如apt操作应该始终以apt-get update && ...开头,apt-get update永远不应该在单独的RUN中层
  2. 最小化层:更少的层通常意味着更好的构建和运行时性能。这通常意味着在可能的情况下组合层
  3. 缓存性能:将可缓存的图层尽可能高地推入文件中,请注意,如果图层无效该图层后面的所有图层也会失效
  4. 鉴于此,这里有一些您提出的建议的观察结果:

    分隔ENV图层

    鉴于上述(2),您应尽可能将ENV个图层组合在一起。用户可以在运行时覆盖--env,这不会影响构建时分层。是的,如果其中一个ENV行在源代码中被修改,它将使文件的其余部分无效(3)但通常会因性能原因而被删除。

    向上移动COPY

    通常这不是一个好主意,磁盘上的源是最可能的要更改的内容,如果源更改,COPY层中的所有层都将失效

    移动EXPOSE

    这无关紧要。 EXPOSE是一个几乎无关紧要的层(事实上,除非你链接容器,否则它什么都不做)。由于它是可缓存的,我把它放在顶部附近,但再次,计算并不会真正改变它是微不足道的。

    摘要

    tl; dr维护者对所有三个更改都说“不”是正确的,因为它会使构建和运行性能变差。