Birden çok FROM - ne anlama geliyor?


113

Github'daki Linkurious projesi için hem Neo4j veritabanının hem de Node.js'nin çalıştırılmasını gerektiren bir docker görüntüsü oluşturmak istiyorum .

İlk yaklaşımım, Neo4j içeren resmim için bir temel resim bildirmekti. Referans dokümanlar "temel resmi" herhangi bir yararlı şekilde tanımlamaz:

Temel görüntü: Üst öğesi olmayan bir görüntü, temel görüntüdür

Okudum ki, o görüntünün kendisinde temel görüntü yoksa yalnızca temel bir görüntüme sahip olabilirim.

ama temel görüntü nedir? neo4j / neo4j'yi bir FROM yönergesinde bildirirsem, görüntüm çalıştırıldığında neo veritabanının otomatik olarak çalışacağı ve 7474 numaralı bağlantı noktasındaki kapsayıcı içinde kullanılabileceği anlamına mı gelir?

Docker referansını okurken (bkz: https://docs.docker.com/reference/builder/#from ) Görüyorum:

FROM, birden çok görüntü oluşturmak için tek bir Dockerfile içinde birden çok kez görünebilir. Her yeni FROM komutundan önce commit ile son resim ID çıktısını not edin.

birden çok görüntü oluşturmak istiyor muyum? neo4j ve node.js gibi diğer görüntülerin içeriğini içeren tek bir görüntüye sahip olmak istediğim görünüyor

Başvuru kılavuzunda bağımlılıkları bildirecek bir yönerge bulamadım. Resmimi çalıştırmak için çağıran bağlamın önce ihtiyaç duyduğu imajları kurması gereken RPM'deki gibi bağımlılıklar yok mu?

Kafam karıştı...


Not: Mayıs 2017, artık FROMbir Dockerfile. Aşağıda düzenlenmiş cevabıma bakın.
VonC

Cevabımı daha temiz bulabilecek misin bak. Ve eğer öyleyse, kabul etmeyi düşünün.
Evan Carroll

Yanıtlar:


113

temel görüntü nedir?

Bir dizi dosya, artı EXPOSE'd bağlantı noktaları ENTRYPOINTve CMD. Bir yönerge ile
yeni bir Dockerfilebaşlangıç ​​yaparak , bu temel görüntüye dayalı olarak dosyalar ekleyebilir ve yeni bir görüntü oluşturabilirsiniz FROM: bundan sonra bahsedilen FROMgörüntü, yeni görüntünüz için "temel görüntü" dür.

Bu neo4j/neo4j, bir FROMyönergede ifade edersem , resmim çalıştırıldığında neo veritabanının otomatik olarak çalışacağı ve 7474 numaralı bağlantı noktasındaki konteyner içinde kullanılabileceği anlamına mı geliyor?

Yalnızca üzerine yazmazsanız CMDve ENTRYPOINT.
Ancak görüntünün kendisi yeterlidir: özel kullanımınızla FROM neo4j/neo4jilgili dosyalar eklemek zorunda kalırsanız a kullanırsınız .neo4jneo4j

FROM tek bir Dockerfile içinde birden çok kez görünebilir

Yapma: bu "özelliği" yine de kaldırmak için bir teklif var ( sorun 13026 )

14412 numaralı sayı şunlardan bahsediyor:

Çoklu kullanmak FROMgerçekten bir özellik değil, bir hatadır (ah, sınır sıkıdır ve FROMbir Dockerfile'da çoklu kullanım durumu çok azdır).


Docker (moby) 17.05-ce ile Mayıs 2017'yi güncelleyin (18 ay sonra) .

Birden çok FROM , tek bir Dockerfile içinde kullanılabilir.
Bkz. " Docker'da Oluşturucu modeli ve Çok aşamalı yapılar " ( Alex Ellis ) ve Tõnis Tiigi tarafından PR 31257 .

Önce:

Oluşturucu modeli, iki Docker görüntüsünün kullanılmasını içerir - biri bir derleme gerçekleştirmek ve diğeri de ilk derlemenin sonuçlarını, ilk görüntüdeki derleme zinciri ve araç oluşturma cezası olmadan göndermek için.

Sonra:

Genel sözdizimi, FROMDockerfile'ınıza ek süreler eklemeyi içerir - hangisi son FROMifade ise son temel görüntüdür. Artefaktları ve ara görüntülerden çıktıları kopyalamak için kullanın COPY --from=<base_image_number>.

Dockerfile'ın ilk bölümü:

FROM golang:1.7.3 as builder
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html  
COPY app.go    .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

Aynı (!) Dockerfile'ın ikinci bölümü :

FROM alpine:latest  
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/github.com/alexellis/href-counter/app    .
CMD ["./app"]  

Sonuç, biri oluşturmak için, diğeri yalnızca sonuçta ortaya çıkan uygulamayı içeren (çok, çok daha küçük) iki resim olacaktır.

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

multi               latest              bcbbf69a9b59        6 minutes ago       10.3MB  
golang              1.7.3               ef15416724f6        4 months ago        672MB  

2
birden çok FROM'un kaldırılmasına yazık. bana en çok, özellikle bağımlılık mekanizmasının yokluğunda faydalı görünüyor. RPM'ler ile, örneğin, paketimin çalışması için başka bir pakete ihtiyacı olduğunu beyan edebilirim, bu nedenle yükleme sırasında her şey benim için ayarlanır. gerçek şu ki, çoğu şey birden fazla bağımlılık gerektirecek, bu yüzden birden fazla FROM'un yokluğunda, bunun nasıl çalışması gerekiyor?
ekkis

3
@ekkis, önceki cevabımda bahsettiğim gibi ( stackoverflow.com/a/33295292/6309 ), sisteminizi, her biri belirli bir hizmet sağlayan ve --link ( docs.docker.com/) aracılığıyla iletişim kuran birden fazla kapsayıcı düzenleyerek çalıştırırsınız. userguide / dockerlinks /… ).
VonC

2
@VonC Elbette, ideal bir dünyada, yeni bir uygulama ve anlaşılan tüm kalıplarla. Bu arada, çözümlerini docker'a taşımaya çalışan ve yazılım bağımlılıkları gibi ağ ile çözülmeyen ihtiyaçlara sahip, hepsi uyumlu bir taban kullanan, ancak birden çok Dockerfilesinden daha fazla sayıda insan olmasını bekliyorum. Bunun yerine, şimdiye kadar bulabildiğim en iyi şey, kendi Dockerfiles'ımı oluşturmak için onları parçalara ayırmak.
rainabba

@rainabba Kabul edildi. Eski monolitler kolayca taşınmaz. İlginç okumalar: martinfowler.com/articles/… , threedots.tech/post/microservices-or-monolith-its-detail , hackernoon.com/…
VonC

2

İlk cevap çok karmaşık, tarihi ve zevklerime göre bilgisiz.


Aslında oldukça basit. Docker, çok aşamalı yapılar adı verilen bir işlevsellik sağlar , buradaki temel fikir,

  • Sizi, istediğiniz şeyi beyaz listeye almaya zorlayarak istemediklerinizi manuel olarak kaldırmak zorunda kalmaktan kurtarır,
  • Aksi takdirde Docker uygulaması nedeniyle alınacak ücretsiz kaynaklar.

İlkinden başlayalım. Çok sık Debian gibi bir şeyle göreceksiniz.

RUN apt-get update \ 
  && apt-get dist-upgrade \
  && apt-get install <whatever> \
  && apt-get clean

Tüm bunları yukarıdakilerle açıklayabiliriz. Yukarıdaki komut birbirine zincirlenmiştir, bu nedenle ara Görüntüler gerekmeden tek bir değişikliği temsil eder. Böyle yazılmışsa

RUN apt-get update ;
RUN apt-get dist-upgrade;
RUN apt-get install <whatever>;
RUN apt-get clean;

Bu, 3 tane daha geçici ara Görüntü ile sonuçlanır. Tek bir görüntüye küçültüldüğünde, geriye kalan bir sorun vardır: apt-get cleankurulumda kullanılan yapıları temizlemiyor. Bir Debian geliştiricisi, kurulumuna sistemi değiştiren bir komut dosyası eklerse, bu değişiklik nihai çözümde de bulunacaktır pepperflashplugin-nonfree(bunun bir örneğine bakın ).

Çok aşamalı bir yapı kullanarak, tek bir değişen eylemin tüm avantajlarından yararlanabilirsiniz, ancak COPY --fromburada belgelenen sözdizimini kullanarak geçici görüntüde tanıtılan dosyaları manuel olarak beyaz listeye almanızı ve kopyalamanızı gerektirecektir . Dahası, alternatifin olmadığı (bir gibi apt-get clean) harika bir çözümdür ve aksi takdirde son görüntünüzde çok sayıda ihtiyaç duyulmayan dosya olur.

Ayrıca bakınız


teşekkürler ama sorunumu nasıl çözdüğünü anlamıyorum. bana göre, FROM bir miras mekanizmasıdır ve birden çok yönergeye sahip olmak, birden çok ebeveynden miras alabileceğim anlamına gelir. cevabınızda
FROM'dan

1
Belki de karışıklık budur. FROMtemelde bir ad alanı bildirimi. Niteleyici, kalıtımdan çok bir uzantı gibidir. Birden çok ad alanı bildirebilirsiniz. Ve bu ad alanlarının her biri başka bir ad alanını genişletebilir. @ekkis Diğer cevap sizin için işe yarıyorsa, o zaman kesinlikle ona bağlı kalın.
Evan Carroll
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.