带有make的Docker:更改Dockerfile上的映像 [英] Docker with make: build image on Dockerfile change

查看:812
本文介绍了带有make的Docker:更改Dockerfile上的映像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用Docker并制作实用程序,并尝试编写仅在Dockerfile更改时重建Docker映像的规则.
我的项目结构如下:

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 .
.
├── Dockerfile
├── Makefile
└── project
    └── 1.js

我的Dockerfile非常简单:

My Dockerfile 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"]

它只是通过安装nodejs来创建简单的ubuntu映像,并从共享目录运行脚本.

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

现在,我想从Makefile运行此图像.更改Dockerfile时,我想重建映像. Makefile如下:

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

default: run 

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

build: Dockerfile
        docker build -t app-server .

现在,当我执行sudo make命令时,它每次都会重建一个图像.

Now when I execute sudo make command it rebuild an image every time.

如何仅在Dockerfile更改时强制make执行构建任务?

How can I force make to execute build task only when Dockerfile changed?

推荐答案

编写时:

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

Make文件中的

期望该配方将创建一个名称为run的文件.然后make将对照先决文件的时间戳检查该文件的时间戳,以确定下次是否需要运行该配方.

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.

与您在makefile中具有的build目标类似.

Similarly with the build target you have in your makefile.

build: Dockerfile
        docker build -t app-server .

但是,这些配方均未使用目标名称创建文件.这意味着make不能使用该文件的时间戳来确定是否需要重新运行配方.因此,make必须假定需要重新运行配方(因为假设否则将意味着该规则将永远不会运行).

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).

如果运行make -rRd,您将看到make的想法正在发生,并且应该看到我刚才所说的内容.

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.

向每个目标简单地添加touch $@(可选地以@前缀以使运行的命令的默认make echo回声)应该足以使它为您工作.

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.

话虽如此,如果您也不想将图章文件也作为根拥有,那么将sudo放在需要它的每个配方行上而不是用sudo运行make可能是有意义的

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.

为便于记录,这在GNU Make手册的 4.8 Empty Target Files to Record Events .

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

这篇关于带有make的Docker:更改Dockerfile上的映像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆