首页 > 解决方案 > Makefile with Docker Compose,如何防止每次都构建?

问题描述

我有Makefile一个 Docker Compose 堆栈:

.PHONY: build

docker-compose.yml:
    cp docker-compose.yml.dist docker-compose.yml

build: docker-compose.yml
    docker-compose -p xxx build

但是每次我启动make build命令docker-compose -p xxx build时都会执行。是否可以仅在需要时运行构建?我想知道这方面的最佳做法,谢谢:)

标签: dockermakefiledocker-compose

解决方案


这种行为是将build目标声明为phony的直接结果。

在它的特定情况下,docker build如果图像中没有任何变化,它应该运行得非常快。(它比重新运行要贵一点make;如果目录树非常大,它只会很慢。)这里的一种方法是忽略它并总是重建东西。

您将在 Makefiles 中看到的另一个常见模式是使用人工文件来跟踪构建管道序列中的特定步骤是否已发生。您需要非常擅长声明所有依赖项才能使其正常工作。

.PHONY: build clean

build: .build.docker

.build.docker: docker-compose.yml Dockerfile app
        docker-compose -f $< build
        touch $@

docker-compose.yml: docker-compose.yml.dist
        cp $< $@

app: $(SOURCES:%=%.o)
        $(CC) -o $@ $(SOURCES:%=%.o) $(LIBS)

clean:
        rm -f .build.docker docker-compose.yml app

假设您更改了docker-compose.yml.dist文件。有了这个 Makefile,它会触发cp它的规则docker-compose.yml,然后是重建图像的规则,然后它会更新.build.docker文件上的时间戳。同样,如果您更新构成应用程序的任何源文件,最终将需要重新构建 Docker 映像。

但是,假设您没有更改任何这些内容。 build是假的,所以它总是被认为是过时的,但它本身没有规则。它检查.build.docker文件的时间戳。因为它比docker-compose.yml,更新Dockerfile,并且app没有什么可做的,并且图像构建被跳过。


推荐阅读