2014-09-30 88 views
5

我在Docker上玩並製作實用程序,並嘗試編寫僅在Dockerfile更改時重新創建Docker鏡像的規則。
我的項目結構如下:Docker with make:在Dockerfile上生成鏡像更改

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發生變化時才強制執行構建任務?

+0

發佈了一些指導你真的應該看看https://docs.docker.com/articles/dockerfile_best-practices/ – 2015-07-14 18:58:08

+0

你可能不需要這麼做。 'docker build'在內部管理這種類型的依賴關係更改,基本上與您嘗試使用'make'實現的效果基本相同。如果您不需要查看狀態,可以使用'--quiet'選項以及'>/dev/null'。 – nobar 2016-06-15 04:48:29

回答

6

當你寫:

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

在makefile化妝預計,該食譜將通過run名稱創建一個文件。然後,make會根據其必備文件的時間戳檢查該文件的時間戳,以確定下次是否需要運行配方。

與您的makefile中的build目標類似。

build: Dockerfile 
     docker build -t app-server . 

但是,這些配方都不是用目標名稱創建文件。這意味着make不能使用該文件的時間戳來確定是否需要重新運行配方。因爲這樣做必須假定它需要重新運行配方(因爲否則將意味着規則永遠不會運行)。

如果你運行make -rRd你會看到什麼讓思考進行,你應該看到我剛纔說的。

因此,您的問題的解決方案是在每個目標中創建戳記文件。

只需將touch [email protected](可選地以@作爲前綴,使默認默認迴應其運行的命令的回顯)添加到每個這些目標應該足以讓它爲您工作。

話雖這麼說,這可能是有意義的把sudo每個需要,而不是與sudo運行make如果你不想郵票文件所擁有的根以及做它的食譜線。

有關記錄,在GNU Make Manual中作爲4.8 Empty Target Files to Record Events的章節進行了討論。

5

您的「目標」defaultrunbuild是「虛假」目標。這是一個抽象的概念,而不是一個真實的文件。這種虛假的目標,不應該有一個配方(因爲你不能讓它們)。它們應該取決於真實文件,或者其他假目標等等,但是一切最終都只能依賴於真實文件。

你的僞目標應標記爲這樣

.PHONY: default run build 

真正的目標,而另一方面,應該有一個配方 - 配方,使該目標。

因此,首先取決於你的假目標,沒有配方,在真正的目標上。

然後有真正的目標有食譜。

我在 makefile enforce library dependency ordering

+0

儘管正確且有用,但僅從最嚴格的意義上說,它回答了所問的問題,因爲它無法幫助OP找出如何讓文件考慮碼頭運行目標的「真實文件」。 (當然,我假設碼頭工人本身並不只是創建一個可以直接依賴的文件。) – 2014-10-01 17:09:08

+0

@EtanReisner是的,我經常不回答這個問題,因爲我認爲這太傲慢了:)最好回答一個不同的問題。 Guity作爲收費的Etan! – 2016-09-03 21:23:19