मल्टीपल फॉर्म्स - इसका क्या मतलब है


112

मैं गिटहब पर लिंकरियस प्रोजेक्ट के लिए एक डॉकटर छवि बनाना चाहता हूं , जिसे चलाने के लिए Neo4j डेटाबेस और Node.js दोनों की आवश्यकता होती है।

मेरा पहला दृष्टिकोण Neo4j युक्त, मेरी छवि के लिए एक आधार छवि घोषित करना था। संदर्भ डॉक्स किसी भी सहायक तरीके से "आधार छवि" को परिभाषित नहीं करते हैं:

आधार छवि: एक छवि जिसमें कोई माता-पिता नहीं है वह आधार छवि है

जिससे मैंने पढ़ा कि मेरे पास केवल आधार छवि हो सकती है यदि उस छवि की कोई आधार छवि नहीं है।

लेकिन आधार छवि क्या है? क्या इसका मतलब यह है कि अगर मैं एक FROM के निर्देश में neo4j / neo4j की घोषणा करता हूं, कि जब मेरी छवि को चलाया जाता है तो neo डेटाबेस स्वचालित रूप से चलेगा और पोर्ट 7474 पर कंटेनर के भीतर उपलब्ध होगा?

डॉकर संदर्भ पढ़ना (देखें: https://docs.docker.com/reference/builder/#from ) मैं देख रहा हूं:

एकाधिक छवियों को बनाने के लिए FROM एक एकल Dockerfile के भीतर कई बार दिखाई दे सकता है। प्रत्येक नई FROM कमांड से पहले कमिट द्वारा अंतिम इमेज आईडी आउटपुट का एक नोट बनाएं।

क्या मैं कई छवियां बनाना चाहता हूं? ऐसा लगता है कि जो मैं चाहता हूं, वह एकल छवि है जिसमें अन्य छवियों जैसे कि neo4j और node.js शामिल हैं

मुझे संदर्भ पुस्तिका में निर्भरता घोषित करने का कोई निर्देश नहीं मिला है। क्या आरपीएम जैसी कोई निर्भरता नहीं है जहां मेरी छवि को चलाने के लिए कॉलिंग संदर्भ को पहले उन छवियों को स्थापित करना होगा जिन्हें इसकी आवश्यकता है?

मैं उलझन में हूं...


नोट: मई २०१ you, अब आपके पास एक FROMमें कई हैं Dockerfile। नीचे मेरा संपादित उत्तर देखें।
वॉनसी

देखें कि आपको मेरा उत्तर क्लीनर मिल रहा है या नहीं। और यदि हां, तो इसे स्वीकार करने पर विचार करें।
इवान कैरोल

जवाबों:


113

आधार छवि क्या है?

फ़ाइलों का एक सेट, प्लस EXPOSEपोर्ट, ENTRYPOINTऔर CMD
आप फ़ाइलों को जोड़ सकते हैं और उस आधार छवि के आधार पर एक नई छवि का निर्माण कर सकते हैं, Dockerfileएक FROMनिर्देश के साथ एक नई शुरुआत कर सकते हैं : बाद FROMमें उल्लिखित छवि आपकी नई छवि के लिए "आधार छवि" है।

इसका मतलब यह है कि अगर मैं neo4j/neo4jएक FROMनिर्देश में घोषणा करता हूं , कि जब मेरी छवि को चलाया जाता है तो नव डेटाबेस स्वचालित रूप से चलेगा और पोर्ट 7474 पर कंटेनर के भीतर उपलब्ध होगा?

केवल तभी जब आप ओवरराइट न करें CMDऔर ENTRYPOINT
लेकिन अपने आप में छवि पर्याप्त है: FROM neo4j/neo4jयदि आप neo4jअपने विशेष उपयोग के लिए संबंधित फ़ाइलों को जोड़ना चाहते थे, तो आप इसका उपयोग करेंगे neo4j

FROM एक डॉकफ़िल के भीतर कई बार दिखाई दे सकता है

नहीं: वैसे भी "सुविधा" को हटाने का प्रस्ताव है ( समस्या 13026 )

अंक 14412 उल्लेख:

एकाधिक FROMका उपयोग करना वास्तव में एक विशेषता नहीं है, लेकिन एक बग (ओह अच्छी तरह से, सीमा तंग है और FROMएक डॉकफेराइल में कई के लिए कुछ उपयोग के मामले हैं )।


अपडेट मई 2017 (18 महीने बाद), docker (moby) के साथ 17.05-CE

मल्टीपल FROM का इस्तेमाल सिंगल डॉकरीफाइल में किया जा सकता है।
" बिल्डर पैटर्न बनाम मल्टी-स्टेज डॉकर्स में निर्माण करता है " ( एलेक्स एलिस द्वारा ) और पीआर 31257 Tiginis Tiigi द्वारा देखें

इससे पहले:

बिल्डर पैटर्न में दो डॉकटर चित्रों का उपयोग करना शामिल है - एक निर्माण करने के लिए और दूसरा पहली छवि में बिल्ड-चेन और टूलींग के दंड के बिना पहले बिल्ड के परिणामों को शिप करने के लिए।

उपरांत:

सामान्य वाक्यविन्यास में FROMआपके डॉकरीफाइल के भीतर अतिरिक्त समय जोड़ना शामिल है - जो भी अंतिम FROMकथन है अंतिम आधार छवि है। मध्यवर्ती छवियों से कलाकृतियों और आउटपुट की प्रतिलिपि बनाने के लिए उपयोग करें COPY --from=<base_image_number>

डॉकफाइल का पहला भाग:

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 .

उसी का दूसरा हिस्सा (!) Dockerfile:

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"]  

परिणाम दो चित्र होंगे, एक भवन के लिए, एक केवल परिणामी एप्लिकेशन के साथ (बहुत, बहुत छोटा)

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

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

2
कई FROM को हटाने के बारे में अफ़सोस। यह मुझे सबसे उपयोगी लगता है, विशेष रूप से निर्भरता तंत्र की अनुपस्थिति में। उदाहरण के लिए, RPMs के साथ, मैं घोषणा कर सकता हूं कि मेरे पैकेज को चलाने के लिए एक और पैकेज की आवश्यकता है ताकि मेरे लिए सब कुछ स्थापित हो जाए। वास्तविकता यह है कि अधिकांश चीजों के लिए कई आश्रितों की आवश्यकता होती है, इसलिए कई FROM की अनुपस्थिति में, कैसे काम करना चाहिए?
एककिस

3
@ekkis जैसा कि मैंने अपने पिछले उत्तर में उल्लेख किया है ( stackoverflow.com/a/33295292/6309 ), आप कई कंटेनरों को ऑर्केस्ट्रेट करके अपना सिस्टम चलाते हैं, प्रत्येक एक विशेष सेवा प्रदान करता है, और --link ( docs.docker.com/) के माध्यम से संचार करता है। userguide / dockerlinks /… )।
VonC

2
@VonC ज़रूर, एक आदर्श दुनिया में, एक नया ऐप और सभी पैटर्न के साथ। इस बीच, मैं उम्मीद करता हूं कि ऐसे लोग हैं जो अपने समाधानों को डॉकटर में माइग्रेट करने की कोशिश कर रहे हैं और ऐसी ज़रूरतें हैं जो नेटवर्किंग द्वारा हल नहीं की गई हैं, जैसे कि सॉफ्टवेयर निर्भरता, सभी एक संगत आधार का उपयोग करते हुए, लेकिन कई डॉकरफाइल्स से। इसके बजाय, अब तक का सबसे अच्छा मैं यह पता लगा सकता हूं कि अपना खुद का निर्माण करने के लिए उनके डॉकरीफाइल्स को अलग कर रहा है।
बरसाती

@्रेनबाबा सहमत हैं। लिगेसी मोनोलिथ आसानी से माइग्रेट नहीं होंगे। दिलचस्प पढ़ता है: martinfowler.com/articles/… , threedots.tech/post/microservices-or-monolith-its-detail , hackernoon.com/…
VonC

2

पहला जवाब मेरे स्वाद के लिए बहुत जटिल, ऐतिहासिक और असंयमी है।


यह वास्तव में सरल है। डॉकर एक कार्यक्षमता के लिए प्रदान करता है जिसे मल्टी-स्टेज कहा जाता है, यहां मूल विचार बनाता है:

  • आप जो चाहते हैं उसे मैन्युअल रूप से हटाने के लिए आपको स्वतंत्र नहीं करते हैं, आपको श्वेतसूची के लिए मजबूर करके जो आप चाहते हैं,
  • नि: शुल्क संसाधन जो अन्यथा डॉकर के कार्यान्वयन के कारण उठाए जाएंगे।

पहले से शुरू करते हैं। बहुत बार डेबियन जैसे कुछ के साथ आप देखेंगे।

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

हम ऊपर के संदर्भ में इस सब की व्याख्या कर सकते हैं। उपरोक्त कमांड को एक साथ जंजीर किया गया है, इसलिए यह एक एकल परिवर्तन का प्रतिनिधित्व करता है जिसमें कोई मध्यवर्ती छवियां आवश्यक नहीं हैं। अगर यह इस तरह लिखा गया था,

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

इसका परिणाम 3 और अस्थायी मध्यवर्ती छवियां होंगी। यह एक छवि के लिए कम होने के बाद, एक शेष समस्या है: apt-get cleanस्थापित में उपयोग की गई कलाकृतियों को साफ नहीं करता है। यदि कोई डेबियन अनुरक्षक अपनी स्क्रिप्ट में शामिल करता है जो सिस्टम को संशोधित करता है जो संशोधन अंतिम समाधान में भी मौजूद होगा ( pepperflashplugin-nonfreeउदाहरण के लिए कुछ ऐसा देखें )।

मल्टी-स्टेज बिल्ड का उपयोग करने से आपको एक ही बदले हुए एक्शन के सभी लाभ मिलते हैं, लेकिन इसके लिए आपको मैन्युअल रूप से सफ़ेद चित्रण करना होगा और उन फ़ाइलों की प्रतिलिपि बनानी होगी जो COPY --fromयहाँ सिंटैक्स डॉक्यूमेंटेड का उपयोग करके अस्थायी छवि में पेश की गई थीं । इसके अलावा, यह एक महान समाधान है जहां कोई विकल्प नहीं है (जैसे apt-get clean), और आपके पास अन्यथा आपकी अंतिम छवि में बहुत सारी अन-जरूरी फाइलें होंगी।

यह सभी देखें


धन्यवाद, लेकिन मैं यह नहीं देखता कि आप मेरे मुद्दे को कैसे संबोधित कर रहे हैं। मेरे लिए, FROM एक विरासत तंत्र है और कई निर्देश होने का मतलब है कि मैं कई माता-पिता से विरासत में मिल सकता हूं। अपने जवाब में आप FROM या दूसरों द्वारा सॉफ्टवेयर की पैकेजिंग का लाभ लेने की अवधारणा का उल्लेख नहीं करते हैं
ekkis

1
शायद यही भ्रम है। FROMमुख्य रूप से एक नाम स्थान की घोषणा है। क्वालिफायर में वंशानुक्रम की तुलना में अधिक विस्तार होता है। आप कई नामस्थानों की घोषणा कर सकते हैं। और उनमें से प्रत्येक नामस्थान एक दूसरे नामस्थान का विस्तार कर सकते हैं। @ekkis यदि दूसरा उत्तर आपके लिए काम करता है, तो हर तरह से इसके साथ रहना चाहिए।
इवान कैरोल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.