我玩Docker并制作实用程序并尝试编写仅在Dockerfile更改时重建docker镜像的规则.
我的项目结构如下:
tree .
.
├── Dockerfile
├── Makefile
└── project
└── 1.js
我的Dockerfile非常简单:
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映像,并从共享目录运行脚本.
现在我想从Makefile运行这个图像.当我更改Dockerfile时,我想重建图像.
Makefile看起来像:
default: run
run: build
docker run -v $(CURDIR)/project:/project app-server
build: Dockerfile
docker build -t app-server .
现在,当我执行sudo make命令时,它每次都会重建一个图像.
如何在Dockerfile更改时强制make执行构建任务?
最佳答案
当你写:
run: build
docker run -v $(CURDIR)/project:/project app-server
在makefile中,make期望该配方将以run的名称创建一个文件.然后,make将检查该文件的时间戳与其先决条件文件的时间戳,以确定下次是否需要运行该配方.
与makefile中的构建目标类似.
build: Dockerfile
docker build -t app-server .
但是,这些配方都没有创建具有目标名称的文件.这意味着make不能使用该文件的时间戳来确定是否需要重新运行配方.因此,make必须假设它需要重新运行配方(因为否则将意味着规则永远不会运行).
如果你运行make -rRd,你会看到make think正在进行什么,你应该看到我刚才所说的内容.
只需添加touch $@(可选地以@为前缀,以使其运行的命令的默认回显),每个目标都应足以使其适用于您.
这就是说,如果你不想让邮票文件也被用作root用户,那么将sudo放在需要它的每个配方行上而不是运行make sudo可能是有意义的.
为了记录,这在GNU Make Manual中作为第4.8 Empty Target Files to Record Events
节讨论.