2016-04-11 32 views
0

Her biri Docker görüntü etiketi olarak kullandığım adlandırılmış bir dizinde bulunan birden fazla Docker dosyası olan bir projem var. Her Dockerfile için bir docker görüntüsünü oluşturmalı, test etmeli ve itmeliyim. GNU Make ile aşağıdaki gibi bir şey yapmak için ne yapmam gerekiyor?makefile - çoklu hedeflere sahip mulitple dosyaları oluşturma

# 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

: o size benzeri verecek haliyle

. Eğer "foo/Dockerfile" var ve "docker build -t foo --force-rm foo" çalıştırırsam, "docker görüntüsü" bir dosya üretir mi? Ve eğer öyleyse, dosyanın adı nedir ve nerede bulunur? – Beta

+0

Merhaba Beta, görüntüler (dosyalar) docker ana bilgisayarında ve kullanılan depolama sürücüsüne bağlı. http://stackoverflow.com/questions/19234831/where-are-docker-images-stored-on-the-host-machine – Tom

+0

Genel olarak, dosyanın nereye gideceğini veya ne yapacağını bilmediğinizi mi kastediyorsunuz? olarak adlandırılabilir? Bu durumda * etkili * makefile kolaydır, ancak * verimli * bir değildir. – Beta

cevap

0

Ben

İlk BUILD değişkeni dikkate ... Bu ne istediğini, ancak emin değilim. üç Dockerfiles varsa:

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 

Ham ama etkili:

foo/Dockerfile 
bar/Dockerfile 
baz/Dockerfile 

o zaman İşte girişimlerinin çift foo bar baz

içermesini BUILDS istiyoruz.

Şimdi kurallar. Normalde bir kuralın hedefi kuralın oluşturduğu bir dosyanın adıdır. Bu durumda bu kongreyi kırmalıyız, çünkü görüntü dosyasının isminin ne olacağını bilmiyoruz. dizin foo/ Yani, eğer biz bir kural build_foo arayabilirdin: Biz mümkün olan her dizin için bir kural yazmak istemiyorum bu yana, otomatik değişkenleri kullanın ve bir pattern rule yaratacak

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

:

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

Şimdi "hepsi oluşturur build_foo will work correctly. And we could write a build` kuralı olun:

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

Ama bu oldukça doğru bir yaklaşım değil. Biz inşa etmek, sonra test etmek ve her bir görüntüyü o sıraya koymak istiyoruz. Biz desen kuralları ile yapabilirsiniz

push_foo: test_foo 

test_foo: build_foo 

:

test_%: build_% 
    ... 

push_%: test_% 
    ... 

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

Şimdi "açıklaması yapmak" her şeyi yapacağız yüzden böyle bir şey istiyorum. (Ve eğer makefile içinde ilk kural olarak release: koyarsanız, varsayılan kural olacaktır ve "make" yeterli olacaktır.)

+0

Ne olağanüstü bir cevap. Teşekkür ederim. Açıklamaları takdir ediyorum ve her iki akışı da gösteriyorum. Tavsiye edilen akışı uyguladık. – Tom

+0

Bu çözüm, 'make build_1.2-node5.10-onbuild' gibi bir kural dışı kural da sağlar - sekme tamamlanması için herhangi bir yol var mı? – Tom

+0

@ Tom: Sekme tamamlandı mı? Yani makefile düzenlediğinizde, sekmeler otomatik olarak ele alınacak mı? Bu metin editörüne bağlıdır. – Beta

0

Beğen @Beta, Neden tüm görüntüleri oluşturmak istediğinizi anlamıyorum daha sonra tüm görüntüleri test edin, daha sonra binasının aksine tüm görüntüleri itin, test edin ve itin; ve ikinci yaklaşım, daha basit ve daha normal bir makefile borç verir. Onları çalıştırmak yapmak için docker komutları Açıkçası

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

, yorumsuz ve geri yükleme: Bu ilk yol yapmak zorunda nedenlerini varsa

, o zaman böyle bir makefile şey gerekiyordu VERSION doğru tanımı.Ben docker aşina değilim

$ 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

Cevap Mike için teşekkürler. Doğru, ama Beta'yı kabul ettim çünkü ilk oldu ve ben de bir anlaşmayı daha da ileri götürmeyi düşündüğümden dolayı, – Tom

+0

@ Ben oldukça katılıyorum. Olağandışı bir sebep olmadıkça böyle yaparsın. –