【问题标题】:Docker with make: build image on Dockerfile change带有 make 的 Docker:在 Dockerfile 更改上构建映像
【发布时间】:2014-11-24 22:22:33
【问题描述】:

我玩 Docker 并制作实用程序,并尝试编写仅在 Dockerfile 更改时重建 docker 映像的规则。
我的项目结构如下:

 tree .
.
├── Dockerfile
├── Makefile
└── project
    └── 1.js

我的 Dockerfile 非常简单:

FROM ubuntu

RUN apt-get update
RUN apt-get install -y curl 
RUN curl -sL https://deb.nodesource.com/setup | sudo bash -
RUN apt-get update
RUN apt-get install -y build-essential nodejs
VOLUME ["/project"]
ENTRYPOINT ["cat"]
CMD ["project/1.js"]

它只是使用 nodejs 安装创建简单的 ubuntu 映像并从共享目录运行脚本。

现在我想从 Makefile 运行这个图像。当我更改 Dockerfile 时,我想重建图像。 Makefile 看起来像:

default: run 

run: build
        docker run -v $(CURDIR)/project:/project app-server 

build: Dockerfile
        docker build -t app-server .

现在当我执行sudo make 命令时,它每次都会重建一个图像。

如何在 Dockerfile 更改时强制 make 执行构建任务?

【问题讨论】:

  • 您可能不需要这样做。 docker build 在内部管理这种类型的依赖关系更改,以与您尝试使用 make 实现的效果基本相同。如果您不需要查看状态,可以使用--quiet 选项和>/dev/null。

标签: makefile docker


【解决方案1】:

当你写作时:

run: build
        docker run -v $(CURDIR)/project:/project app-server 

在 makefile 中,make 期望该配方将创建一个名为 run 的文件。然后,make 将根据其必备文件的时间戳检查该文件的时间戳,以确定下次是否需要运行该配方。

与您在 makefile 中的 build 目标类似。

build: Dockerfile
        docker build -t app-server .

然而,这些配方都不会创建具有目标名称的文件。这意味着 make 无法使用该文件的时间戳来确定是否需要重新运行配方。因此 make 必须假设它需要重新运行配方(因为假设否则意味着规则永远不会运行)。

如果您运行 make -rRd,您将看到 make 的想法,您应该会看到我刚才所说的指示。

因此,您的问题的解决方案是在每个目标中创建标记文件。

只需将touch $@(可选前缀@ 以使其运行的命令的默认回显静音)添加到这些目标中的每一个就足以让它为您工作。

话虽如此,如果您不希望标记文件也以 root 身份拥有,则将 sudo 放在需要它的每个配方行上而不是运行 make 和 sudo 可能是有意义的.

作为记录,这在 GNU Make 手册中作为 4.8 Empty Target Files to Record Events 部分进行了讨论。

【讨论】:

    【解决方案2】:

    您的“目标”defaultrun 和 build 是“虚假”目标。那是一个抽象的概念,而不是一个真实的文件。这样的虚假目标不应该有配方(因为你不能制作它们)。相反,它们应该依赖于真实文件,或者可能是其他虚假目标,等等,但一切最终都必须只依赖于真实文件。

    你的虚假目标应该这样标记

    .PHONY: default run build
    

    另一方面,真正的目标应该有一个配方 - 配方就是那个目标。

    因此,首先将您的虚假目标(没有配方)依赖于真实目标。

    然后有真正的目标有配方。

    我已经在 makefile enforce library dependency ordering

    【讨论】:

    • 虽然正确且有用,但仅从最严格的意义上讲,这无法回答所提出的问题,因为它无助于 OP 弄清楚如何获取文件以考虑泊坞窗运行目标。 (当然,我假设 docker 本身并不只是创建一个可以直接依赖的文件。)
    • @EtanReisner 是的,我经常不回答提出的问题,因为我傲慢地认为:) 最好回答一个不同的问题。 Guity 被指控为 Etan!
    猜你喜欢
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 2018-04-23
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    • 2017-04-16
    • 2020-10-17
    相关资源
    最近更新 更多