我玩Docker并制作实用程序并尝试编写仅在Dockerfile更改时重建docker镜像的规则.
我的项目结构如下:
tree .
.
??? Dockerfile
??? Makefile
??? project
??? 1.js
Run Code Online (Sandbox Code Playgroud)
我的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"]
Run Code Online (Sandbox Code Playgroud)
它只是通过nodejs安装创建简单的ubuntu映像,并从共享目录运行脚本.
现在我想从Makefile运行这个图像.当我更改Dockerfile时,我想重建图像.Makefile看起来像:
default: run
run: build
docker run -v $(CURDIR)/project:/project app-server
build: Dockerfile
docker build -t app-server .
Run Code Online (Sandbox Code Playgroud)
现在当我执行sudo make命令时,它每次都会重建一个图像.
如何在Dockerfile更改时强制make执行构建任务?
Eta*_*ner 11
当你写:
run: build
docker run -v $(CURDIR)/project:/project app-server
Run Code Online (Sandbox Code Playgroud)
在makefile中,make期望该配方将按名称创建一个文件run.然后,make将检查该文件的时间戳与其先决条件文件的时间戳,以确定下次是否需要运行该配方.
与build您在makefile中的目标类似.
build: Dockerfile
docker build -t app-server .
Run Code Online (Sandbox Code Playgroud)
但是,这些配方都没有创建具有目标名称的文件.这意味着make不能使用该文件的时间戳来确定是否需要重新运行配方.因此,make必须假设它需要重新运行配方(因为否则将意味着规则永远不会运行).
如果你跑步,make -rRd你将会看到让人想到的是什么,你应该看到我刚刚说过的话.
因此,解决您的问题的方法是在每个目标中创建戳记文件.
只需添加touch $@(可选择加上@默认值,使其默认运行命令的回显)到每个目标应该足以让它适合您.
这就是说,如果你不希望邮票文件也被拥有为root ,那么放上sudo需要它的每个配方行而不是运行它可能是有意义的.makesudo
对于记录,这将在GNU Make Manual中作为部分进行讨论4.8 Empty Target Files to Record Events.
你的"目标" default run并且build是"假的"目标.这是一个抽象概念,而不是真正的文件.这样的虚假目标,不应该有一个配方(因为你不能制作它们).它们应该依赖于真实文件,或者其他虚假目标等等,但是一切都必须最终只依赖于真实文件.
您的虚假目标应该标记为这样
.PHONY: default run build
Run Code Online (Sandbox Code Playgroud)
另一方面,真正的目标应该有一个配方 - 配方制定了目标.
所以,首先要将你的虚假目标,没有食谱,放在真正的目标上.
然后有真正的目标有食谱.
我在makefile强制库依赖项排序中发布了一些指南
| 归档时间: |
|
| 查看次数: |
13302 次 |
| 最近记录: |