Docker with make: create an image on Dockerfile change

I play with Docker and make a utility and try to write a rule that rebuilds the docker image only when the Dockerfile changes.
My project structure is as follows:

tree . . โ”œโ”€โ”€ Dockerfile โ”œโ”€โ”€ Makefile โ””โ”€โ”€ project โ””โ”€โ”€ 1.js 

My Docker file is pretty simple:

 FROM ubuntu RUN apt-get update RUN apt-get install -y curl RUN curl -sL https://deb.nodesource.com/setup | sudo bash - RUN apt-get update RUN apt-get install -y build-essential nodejs VOLUME ["/project"] ENTRYPOINT ["cat"] CMD ["project/1.js"] 

It just creates a simple ubuntu image with the installation of nodejs and runs the script from a shared directory.

Now I want to run this image from the Makefile. When I change the Dockerfile, I want to rebuild the image. The Makefile looks like this:

 default: run run: build docker run -v $(CURDIR)/project:/project app-server build: Dockerfile docker build -t app-server . 

Now, when I execute the sudo make , it restores the image every time.

How to force execution to complete the build task only when the Dockerfile is modified?

+5
source share
2 answers

When you write:

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

in the makefile, make expects this recipe to create a file called run . make will check this fileโ€™s timestamp against the timestamp of its required files to determine if this recipe should be repeated next time.

Similarly with the build tag that you have in your makefile.

 build: Dockerfile docker build -t app-server . 

However, none of these recipes creates files with the name of the target. This means that make cannot use the timestamp of this file to determine if the recipe needs to be run again. Since such a make should assume that it needs to re-run the recipe (because assuming it is different, this rule will never work).

If you run make -rRd , you will see what makes your thoughts, and you should see what I just said.

So the solution to your problem is to create stamp files for each of these purposes.

Just adding touch $@ (optionally with the @ prefix to make it turn off by default the execution of the echo of the commands that it runs) for each of these should be enough to make you work for you.

We believe that it makes sense to put sudo on each line of the recipe that it needs, instead of running make with sudo , if you do not want the stamp files to also be root.

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

+6
source

Your default run and build goals are fake goals. This is an abstract concept, not a real file. Such fake goals should not have a recipe (because you cannot make them). Instead, they should depend on real files or, possibly, other fake goals, etc., but in the end it all depends on real files.

Your fictitious goals should be marked as such.

 .PHONY: default run build 

Real goals, on the other hand, must have a recipe - a recipe makes that goal.

So, first, depend on your fictitious goals, without a prescription, on the real target (s).

Then real goals have recipes.

I published some recommendations on makefile for ordering library dependencies

+5
source

Source: https://habr.com/ru/post/1203701/


All Articles