Incrementally build Docker image hierarchy with Makefile

In a project of mine I have several Docker images that base on each others, because I don’t need to rebuild basic parts of it every time and just want to incrementally build the upper layers of the hierarchy.

I build the images by means of a Makefile. I do this because I’m admittedly lazy and don’t want to enter the whole docker build commands manually every time. And also because I want to avoid making mistakes in the process.

  • I keep getting a 404 error when trying to push to my private repository. Why?
  • Oauth authentication in Apache SuperSet
  • Hadoop “Unable to load native-hadoop library for your platform” error on docker-spark?
  • Docker-compose up does not start a container
  • Node.js Docker image environment variables
  • Error getting IP address: Something went wrong running an SSH command! command
  • What I would like to do now is make make able to detect whether a Docker image has to be rebuild instead of Docker itself because for the latter the Docker build context has to be sent to the Docker daemon every time. The image is quite large because it is based on ubuntu:xenial and so the “Sending build context to Docker daemon” always takes a lot of time for each individual Docker image, independently of whether they need to be rebuilt or not.

    If make was able to detect whether the docker build command needs to be executed that would help a lot to speed up the process.

    So I would like to know if there’s a way for make to detect if a specific Docker image needs to be rebuilt.

  • Pushing docker image to new docker hub account fails
  • Meaning of docker-compose exit code?
  • Docker Remote API does not list containers
  • mysql in docker container can't run through a mounted volume on os x
  • How to configure rabbitmq.config inside Docker containers?
  • Rancher slow performance deploying new docker image
  • One Solution collect form web for “Incrementally build Docker image hierarchy with Makefile”

    Assuming:

    • your docker images are named dia, dib, dic
    • their respective docker files are named dockerfile.dia, dockerfile.dib, dockerfile.dic
    • their corresponding build directories are ./dia.dir/, ./dib.dir/, ./dic.dir/
    • dia depends on files foo, bar in ./dia.dir/
    • dib depends on file cuz in ./dib.dir/ and the docker image dia
    • dic depends on file baz in ./dic.dir/ and the docker image dib

    you can try something like (not tested):

    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)
    

    It should rebuild the docker images only if their docker file changed, or the files they depend on in their directories changed, or the docker image they depend on, changed.

    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.