【问题标题】:Incrementally build Docker image hierarchy with Makefile使用 Makefile 增量构建 Docker 镜像层次结构
【发布时间】:2017-07-07 11:26:27
【问题描述】:

在我的一个项目中,我有几个基于彼此的 Docker 映像,因为我不需要每次都重新构建它的基本部分,而只想逐步构建层次结构的上层。

我通过 Makefile 构建图像。我这样做是因为我承认我很懒,不想每次都手动输入整个docker build 命令。也因为我想避免在这个过程中犯错误。

我现在想做的是让make 能够检测是否必须重建 Docker 映像而不是 Docker 本身,因为对于后者,每次都必须将 Docker 构建上下文发送到 Docker 守护进程。该映像非常大,因为它基于 ubuntu:xenial,因此“将构建上下文发送到 Docker 守护程序”对于每个单独的 Docker 映像总是需要大量时间,无论它们是否需要重建。

如果make 能够检测到是否需要执行docker build 命令,这将有助于加快进程。

所以我想知道make 是否有办法检测是否需要重建特定的 Docker 映像。

【问题讨论】:

  • 需要重建 docker 的标准是什么? (如果它只是一个时间戳比较,那么它很简单,否则,您可能会在配方中创建一个脚本来有条件地重建)。您需要提供更多信息以便他人有效地帮助您。
  • 标准可以是任何使 Docker 重建 Docker 映像层的条件。如果无事可做,作为图像一部分的每一层都将从缓存中加载,而不是重建。在那种情况下,可以从缓存中选择所有层,我希望make 能够跳过整个 docker build 命令。我不确定 Docker 如何检测层是否需要重建,以及是否不可避免地将构建上下文发送到 Docker 守护进程。
  • 只是一个快速的免责声明:我对 docker 本身一无所知。但是,话虽如此,我是否可以假设每个 docker 映像都在其自己的单独目录中,并且 docker 不依赖于该目录之外的任何内容?
  • touch 命令是您的朋友,在这里:使用它在每个 Docker 构建结束时创建(或更新最后修改日期)一个空文件。并声明它们之间的依赖关系。

标签: docker makefile


【解决方案1】:

假设:

  • 你的 docker 镜像被命名为diadibdic...
  • 它们各自的 docker 文件被命名为 dockerfile.diadockerfile.dibdockerfile.dic...
  • 它们对应的构建目录是./dia.dir/./dib.dir/./dic.dir/...
  • dia 取决于 ./dia.dir/ 中的文件 foobar
  • dib 取决于 ./dib.dir/ 中的文件 cuz 和 docker 映像 dia
  • dic 取决于 ./dic.dir/ 中的文件 baz 和 docker 映像 dib

您可以尝试类似(未测试):

DOCKERIMAGES := dia dib dic
TAGS := $(patsubst %,.%.tag,$(DOCKERIMAGES))
diaDEPS := foo bar
dibDEPS := cuz
dicDEPS := baz

all: $(TAGS)

$(TAGS): .%.tag: dockerfile.%
    docker build -f $< -t $* $*.dir && \
    echo '$* image built' && \
    touch $@

define DEPS_rule
.$(1).tag: $$(addprefix $(1).dir/,$$($(1)DEPS))
endef

$(foreach d,$(DOCKERIMAGES),$(eval $(call DEPS_rule,$(d))))

.dib.tag: .dia.tag
.dic.tag: .dib.tag

clean:
    rm -f $(TAGS)

只有当他们的 docker 文件改变,或者他们在他们的目录中依赖的文件改变,或者他们依赖的 docker 镜像改变时,它才应该重建 docker 镜像。

【讨论】:

  • 我现在正在使用这个解决方案,至少从中得到了一些启发。奇迹般有效。谢谢!
  • 非常好!伟大的思想都一样 @renaud-pacalet ;) 因为我在 stackoverflow.com/a/65913861/23023 中写了一个类似的食谱 - 虽然没有回答图像间依赖问题。
【解决方案2】:

您可以尝试使用一个名为docker-bakery 的小工具来分析dockerfiles 的结构并在父图像更改时触发分层构建。

例如当dog图像发生变化时,子图像可以自动重建。

├── alpine-java
│   ├── bird
│   └── mammal
│       ├── cat
│       ├── dog
│       │   ├── dobermann
│       │   │   └── smaller-dobermann
│       │   ├── pitbull
│       │   └── labrador
│       └── horse
└── scratch
    └── fish

dog 重建时的调用可以很简单:

$/docker-bakery-example> cd dog
$/dog> make build-major-all
...
// docker build of child images
... 
$/dog> make push-major-all

这里有一个example projectdockerfilesmake 文件,使用起来非常方便。

【讨论】:

    猜你喜欢
    • 2019-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-16
    • 2020-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多