Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make: dependency on a docker image

I'm using a docker workflow to generate some files, based on a given spec file, with the Makefile being (it's generating a client according to an OpenAPI spec):

SWAGGER ?= ${PWD}/swagger.yaml
GENERATOR ?= openapitools/openapi-generator-cli\:latest

generated: Makefile ${SWAGGER}
    docker run --rm --user $$(id -u):$$(id -g) \
    -v ${PWD}:/output -v ${SWAGGER}:/input/swagger.yaml \
    ${GENERATOR} \
    generate -g python -i /input/swagger.yaml -o /output/generated \

this works fine, and will rebuild if I modify the input SPEC file.

But it doesn't rebuild when the docker image is changed.

Let's say I docker build the image with the same name:tag again, but with different code inside, or I use a different tagged version of the upstream image, whatever. This is kind of expected because the Makefile has no knowledge of the docker image's content or modification date. How can I make the Makefile understand the dependency on the docker image ?

  • I've tried to docker inspect the image to fetch the creation date, but I don't know how to make make understand that as a dependency (if the creation date is newer than the output dir, then rebuild)
  • I can't just add a dependency on the code inside the docker image, because the docker image might not even have been built from locally available files.

make might not be the tool for that kind of thing, maybe there is something else that I could use that understands the docker image dependency.

like image 891
rienafairefr Avatar asked Aug 08 '26 20:08

rienafairefr


1 Answers

Whether the artifact you depend on is a Docker image or some service/data somewhere else, you need to represent what you know about it, in the form of a regular file. Because make only deals with files. :-)

I'd recommend you define some macro for "invoke docker build and save evidence of its success to a marker file with predictable name" so that you can use that to replace all calls to docker build, ensure consistent file handling. Full-blown example, assuming a/Dockerfile and b/Dockerfile exist.

# For consistency, the src dirs are named like the images they produce
IMAGES = a b

# Keep "stamps" around, recording that images were built. 
# You could keep them in e.g. a `.docker-buildstamps/*` dir, 
# but this example uses `*/docker-buildstamp`.
BUILDSTAMP_FILE = docker-buildstamp
BUILDSTAMPS = $(addsuffix /$(BUILDSTAMP_FILE),$(IMAGES))

.PHONY: all
all: $(BUILDSTAMPS)

# Pattern rule: let e.g. `a/docker-buildstamp` depend on changes to `a/*` (-but avoid circular dep)
%/$(BUILDSTAMP_FILE): % %/[!$(BUILDSTAMP_FILE)]*
    $(docker_build)

clean:
    docker image rm -f $(IMAGES)
    rm -f $(BUILDSTAMPS)

# Turn `a/docker-buildstamp` back into `a`
define from_buildstamp
$(@:%/$(BUILDSTAMP_FILE)=%)
endef

# Self-explanatory
define docker_build
docker build -t $(from_buildstamp) $(from_buildstamp) 
touch $@
endef
like image 168
conny Avatar answered Aug 10 '26 14:08

conny



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!