目标相关性是命令的输出

时间:2019-11-18 22:11:38

标签: docker makefile

我有一个带有docker配方的Makefile,该配方通过执行make docker来构建docker镜像。食谱如下:

# Build the docker file
docker: .setup ${GOBLDDIR}/docker-image

我想进行设置,以确保在所有内容均为最新时都不会重建docker文件,因此我设置了${GOBLDDIR}/docker-image依赖关系。这种依赖关系只是一个带有Docker映像ID的文本文件。这是食谱,实际上是由docker构建的:

# DO THE DOCKER BUILD
${GOBLDDIR}/docker-image: ${GOBLDDIR} ${GOSRCFILES} go.mod Makefile Dockerfile
# Vendor our dependencies so we don't have to download them in the docker container
        go mod vendor
# Wherever the config lives, we need it to be in the Docker build context
        mkdir -p ./.docker-files
        cp ${TFOUT} ./.docker-files/config.json
# The go app is actually compiled within this dockerfile
        docker build . -t ${GOCMD} --build-arg AWS_PROFILE=${AWS_PROFILE} --build-arg SVC=${GOCMD} --build-arg VERSTR=${VERSTR}
        docker images ${GOCMD} -q > ${GOBLDDIR}/docker-image
        docker tag ${GOCMD}:latest ${GOCMD}:dev
        docker tag ${GOCMD}:latest ${GOCMD}:${VERSTR}
# Clean up the crap we created just to build the Dockerfile
        rm -rf vendor/
        rm -rf ./.docker-files

也许这是一个疯狂的设计-对我有这种感觉。在某些情况下,有时它不起作用。我愿意接受其他想法。

尤其是,有没有一种方法可以使依赖关系不是文件,而是命令的结果?例如,类似docker inspect -f '{{ .Created }}' MY_IMAGE_NAME

1 个答案:

答案 0 :(得分:1)

您的方法通常是一个好的方法。您可以添加检查的时间不一定是创建时间的时间戳,而是可以检查图像是否确实是您先前构建的(其他人可能已经构建了具有不同内容的较新图像,可能不再反映您的存储库)。

通常,make通过比较依赖项的时间戳来决定是否建立目标,因此它们是最常见的文件。但是,可以使用一些逻辑来处理依赖项列表,这使您可以运行任意检查。

在您的方案中,您已经将图像ID存储在文件中。现在,这可以用于检查当前图像ID是否与我们先前构建的ID相同。我们可以根据依赖关系评估来比较同一命令的输出(提取为DRY-ness的变量)与存储的内容;如果它们不匹配,我们将发布FORCE的依赖项.PHONY,因此总是过时,从而有效地触发目标重拍:

$ cat Makefile
docker-id = docker image ls -q $(DOCKER_IMAGE)

docker-image: Dockerfile $(if $(findstring $(shell $(docker-id)),$(file <docker-image)),,FORCE)
        docker build . -t $(DOCKER_IMAGE)
        $(docker-id) > $@

.PHONY: FORCE

输出:

# Initial image build
$ make docker-image DOCKER_IMAGE=test
docker build . -t test
Sending build context to Docker daemon 7.168 kB
Step 1/2 : FROM alpine
 ---> 965ea09ff2eb
Step 2/2 : RUN echo 16517
 ---> Running in 6a9601225516

16517
 ---> 54b651cb8912
Removing intermediate container 6a9601225516
Successfully built 54b651cb8912
docker image ls -q test > docker-image

# No files changed, image exists
$ make docker-image DOCKER_IMAGE=test
make: 'docker-image' is up to date.

# Changing Dockerfile forces rebuild
$ touch Dockerfile
$ make docker-image DOCKER_IMAGE=test
docker build . -t test
Sending build context to Docker daemon 7.168 kB
Step 1/2 : FROM alpine
 ---> 965ea09ff2eb
Step 2/2 : RUN echo 16517
 ---> Using cache
 ---> 54b651cb8912
Successfully built 54b651cb8912
docker image ls -q test > docker-image

# Mismatched id forces rebuild
$ echo foobar > docker-image
$ make docker-image DOCKER_IMAGE=test
docker build . -t test
Sending build context to Docker daemon 7.168 kB
Step 1/2 : FROM alpine
 ---> 965ea09ff2eb
Step 2/2 : RUN echo 16517
 ---> Using cache
 ---> 54b651cb8912
Successfully built 54b651cb8912
docker image ls -q test > docker-image

# Missing image forces rebuild
$ docker image rm test
Untagged: test:latest
Deleted: sha256:54b651cb8912a5d2505f1f92c8ea4ee367cdca0d3f8e6f1ebc69d0cf646ca72c
Deleted: sha256:3749695bf207f2ca0829d8faf0ef538af1e18e8c39228347f48fd6d7c149f73a
$ make docker-image DOCKER_IMAGE=test
docker build . -t test
Sending build context to Docker daemon 7.168 kB
Step 1/2 : FROM alpine
 ---> 965ea09ff2eb
Step 2/2 : RUN echo 16517
 ---> Running in 70f8b09a92b3

16517
 ---> 8bdfdfff9db2
Removing intermediate container 70f8b09a92b3
Successfully built 8bdfdfff9db2
docker image ls -q test > docker-image