Docker with make: build image on Dockerfile change

后端 未结 2 1411
北荒
北荒 2021-02-06 05:10

I playing with Docker and make utility and try to write rule which rebuilds docker image only on Dockerfile change.
My project structure looks like:

 tree .         


        
相关标签:
2条回答
  • 2021-02-06 05:49

    Your "targets" default run and build are "phony" targets. That is an abstract concept, not a real file. Such phony targets, should not have a recipe (because you can't make them). They should instead depend on real files, or perhaps other phony targets, and so on, but everything must eventually depend on real files only.

    Your phony targets should be marked as such

    .PHONY: default run build
    

    The real targets, on the other hand, should have a recipe - the recipe makes that target.

    So, first depend your phony targets, without a recipe, on a real target(s).

    Then have real targets have recipes.

    I have posted some guidelines at makefile enforce library dependency ordering

    0 讨论(0)
  • 2021-02-06 05:55

    When you write:

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

    in a makefile make expects that that recipe will create a file by the name of run. make will then check that file's timestamp against the timestamp of its prerequisite files to determine if the recipe needs to be run the next time.

    Similarly with the build target you have in your makefile.

    build: Dockerfile
            docker build -t app-server .
    

    Neither of those recipes create files with the name of the target however. This means that make cannot use the timestamp of that file to determine whether it needs to re-run the recipe. As such make has to assume that it needs to re-run the recipe (because assuming otherwise would mean the rule would never run).

    If you run make -rRd you will see what make thinks is going on and you should see indication of what I've just said.

    The solution to your problem, therefore, is to create stamp files in each of those targets.

    Simply adding touch $@ (optionally prefixed with @ to silence the default make echoing of commands it runs) to each of those targets should be enough to get this to work for you.

    That being said it might make sense to put sudo on each of the recipe lines that need it instead of running make with sudo if you don't want the stamp files to be owned as root as well.

    For the record this is discussed in the GNU Make Manual as section 4.8 Empty Target Files to Record Events.

    0 讨论(0)
提交回复
热议问题