2016-04-11 11 views
0

複数のDockerfilesを持つプロジェクトがあります。各プロジェクトはDockerイメージタグとして使用する名前付きディレクトリにあります。 Dockerfileごとにドッカー画像を構築、テスト、プッシュする必要があります。 GNU Makeで次のようなことをするには、私は何をする必要がありますか?makefile - 複数のターゲットを持つ複数のファイルを構築する

# BUILDS needs to be a list of directories, not a list of Dockerfiles 
BUILDS := $(wildcard */Dockerfile) 
VERSION := $(shell git rev-parse --short=12 --verify HEAD) 
DOCKER_REPO_URL := quay.io/reponame 

define docker_build = 
$(1): 
    @echo "Building [email protected]" 
    docker build -t [email protected] --force-rm [email protected] 
endef 

define docker_test = 
$(1): 
    @echo "Testing [email protected]" 
    docker inspect [email protected] 
    docker run --rm [email protected] help 
endef 

define docker_push = 
$(1): 
    @echo "Pushing [email protected]" 
    docker tag [email protected] $(DOCKER_REPO_URL):[email protected]$(VERSION) 
    docker push $(DOCKER_REPO_URL):[email protected]$(VERSION) 
    docker tag [email protected] $(DOCKER_REPO_URL):[email protected] 
    docker push $(DOCKER_REPO_URL):[email protected] 
endef 

.PHONY: all build test release clean 

all: build test release 

build: $(BUILDS) 
$(foreach build,$(BUILDS),$(eval $(call docker_build,$(build)))) 

test: $(BUILDS) 
$(foreach test,$(BUILDS),$(eval $(call docker_test,$(test)))) 

release: 
$(foreach image,$(BUILDS),$(eval $(call docker_push,$(image)))) 
+0

:それはあなたのようなを与える現状では

。私が 'foo/Dockerfile'を持っていて、' docker build -t foo --force-rm foo'を実行すると、ファイルを生成する "ドッカー画像"ですか?もしそうなら、ファイルの名前は何ですか?ファイルの名前はどこにありますか? – Beta

+0

Hello Betaでは、画像(ファイル)はドッカーホスト上にあり、使用されるストレージドライバに依存します。 http://stackoverflow.com/questions/19234831/where-are-docker-images-stored-on-the-host-machine – Tom

+0

一般的に、ファイルがどこに行くのか、それが何か呼び出される?その場合、*効果的な* makefileは簡単ですが、*効率的なものはありません。 – Beta

答えて

0

私は、これはあなたが望むものであるわからないんだけど、...

まずBUILD変数を考慮してください。私たちは3 Dockerfiles持ちの場合:

foo/Dockerfile 
bar/Dockerfile 
baz/Dockerfile 

をし、我々はBUILDSはここfoo bar baz

を入れたいの試みのカップルです:

BUILDS := $(wildcard */Dockerfile) # this is foo/Dockerfile bar/Dockerfile baz/Dockerfile 

BUILDS := $(dir $(wildcard */Dockerfile)) # this is foo/ bar/ baz/ 

BUILDS := $(patsubst %/,%, $(dir $(wildcard */Dockerfile))) # this is foo bar baz 

原油だが効果的。

今やルール。通常、ルールのターゲットは、ルールが構築するファイルの名前です。この場合、イメージファイルの名前がわからないので、この規則を破る必要があります。ディレクトリがfoo/であれば、我々はbuild_fooルールと呼ばれている可能性:

build_foo: 
    @echo "Building foo" 
    @echo docker build -t foo --force-rm foo 

我々はあらゆる可能なディレクトリのためのルールを記述する必要はありませんので、我々は自動変数を使用してpattern rule作成します。

build_%: 
    @echo "Building [email protected]" 
    @echo docker build -t $* --force-rm $* 

今「それらのすべてを構築するbuild_foo will work correctly. And we could write a build`ルール作り:

build: $(addprefix build_,$(BUILDS)) 

をしかし、これはありますかなり正しいアプローチではありません。私たちはビルドし、次にテストし、各イメージをその順に押したいと思っています。私たちは、パターンルールでこれを行うことができます

push_foo: test_foo 

test_foo: build_foo 

test_%: build_% 
    ... 

push_%: test_% 
    ... 

release: $(addprefix push_,$(BUILDS)) 

今すぐ「のリリースを作る」全力を尽くしますので、我々はこのような何かをしたいと思います。 (そして、 release:をメークファイルの最初のルールとして置くと、それがデフォルトのルールになり、 "make"で十分です。)

+0

どのような優れた答え。ありがとうございました。私は、説明と両方の流れを実証することに感謝します。私は推薦された流れを実装しました。 – Tom

+0

この解決策では、 'make build_1.2-node5.10-onbuild'のような1つのルールを許可します。 – Tom

+0

@Tom:タブ補完?メイクファイルを編集すると、タブは自動的に世話されるようになっていますか?テキストエディタによって異なります。 – Beta

0

なぜ私はすべての画像を構築するのかわかりません、 すべての画像をテストし、 とは対照的に、すべての画像をプッシュします。各画像を構築、テスト、プッシュします。後者の方法は、よりシンプルで普通のmakefileには が適しています。

あなたはそれを最初の方法を行うために持つための理由がある場合は、あなたがこのような メイク何か必要があると思います:、明らかに

# Assuming each subdirectory `foobar` containing a Dockerfile 
# is where we `docker build` the image `foobar` 
IMAGES := $(patsubst %/,%,$(dir $(wildcard */Dockerfile))) 
BUILD_TARGS = $(patsubst %,build_%,$(IMAGES)) 
TEST_TARGS = $(patsubst %,test_%,$(IMAGES)) 
PUSH_TARGS = $(patsubst %,push_%,$(IMAGES)) 

VERSION := 1 # $(shell git rev-parse --short=12 --verify HEAD) 
DOCKER_REPO_URL := quay.io/reponame 

define docker_build = 
build_$(1): 
    @echo "Building $(1)" 
    #docker build -t $(1) --force-rm $(1) 
endef 

define docker_test = 
test_$(1): 
    @echo "Testing $(1)" 
    #docker inspect $(1) 
    #docker run --rm $(1) help 
endef 

define docker_push = 
push_$(1): 
    @echo "Pushing $(1)" 
    #docker tag $(1) $(DOCKER_REPO_URL):$(1)-$(VERSION) 
    #docker push $(DOCKER_REPO_URL):$(1)-$(VERSION) 
    #docker tag [email protected] $(DOCKER_REPO_URL):$(1) 
    #docker push $(DOCKER_REPO_URL):$(1) 
endef 

.PHONY: all build test release clean $(IMAGES) $(BUILD_TARGS) $(TEST_TARGS) $(PUSH_TARGS) 

all: build test release 

build: $(BUILD_TARGS) 
test: $(TEST_TARGS) 
release: $(PUSH_TARGS) 

$(foreach image,$(IMAGES),$(eval $(call docker_build,$(image)))) 
$(foreach image,$(IMAGES),$(eval $(call docker_test,$(image)))) 
$(foreach image,$(IMAGES),$(eval $(call docker_push,$(image)))) 

をそれらを実行するためにdockerコマンドのコメントを外し、および復元 正しい定義はVERSIONです。私はドッキングウィンドウに慣れていないです

$ make 
Building foo 
#docker build -t foo --force-rm foo 
Building bar 
#docker build -t bar --force-rm bar 
Testing foo 
#docker inspect foo 
#docker run --rm foo help 
Testing bar 
#docker inspect bar 
#docker run --rm bar help 
Pushing foo 
#docker tag foo quay.io/reponame:foo-1 
#docker push quay.io/reponame:foo-1 
#docker tag push_foo quay.io/reponame:foo 
#docker push quay.io/reponame:foo 
Pushing bar 
#docker tag bar quay.io/reponame:bar-1 
#docker push quay.io/reponame:bar-1 
#docker tag push_bar quay.io/reponame:bar 
#docker push quay.io/reponame:bar 
+0

マイクさん、ありがとうございました。それは正しいですが、それが最初であったので私はベータを受け入れました。そして、それは理解を伝えるためにさらに進むと思うからです。 – Tom

+0

@Tom私はかなり同意します。珍しい理由がないかぎり、あなたはそうするでしょう。 –

関連する問題