डॉकटर छवि वास्तव में फाइलसिस्टम परतों की एक लिंक की गई सूची है। Dockerfile में प्रत्येक निर्देश एक फाइल सिस्टम लेयर बनाता है जो संबंधित निर्देश के निष्पादन से पहले और बाद में फाइल सिस्टम में अंतर का वर्णन करता है। docker inspectSubcommand फाइल सिस्टम परतों के एक लिंक्ड सूची होने के अपने स्वभाव प्रकट करने के लिए एक डोकर छवि पर इस्तेमाल किया जा सकता।
एक छवि में उपयोग की जाने वाली परतों की संख्या महत्वपूर्ण है
- छवियों को धकेलने या खींचने पर, क्योंकि यह समवर्ती अपलोड या डाउनलोड करने की संख्या को प्रभावित करता है।
- कंटेनर को शुरू करते समय, चूंकि परतों को संयुक्त रूप से कंटेनर में उपयोग किए जाने वाले फाइल सिस्टम का उत्पादन करने के लिए किया जाता है; अधिक परतें शामिल होती हैं, प्रदर्शन जितना बुरा होता है, लेकिन अलग-अलग फाइल सिस्टम बैकएंड इससे अलग प्रभावित होते हैं।
यह कैसे छवियों का निर्माण किया जाना चाहिए के लिए कई परिणाम हैं। पहली और सबसे महत्वपूर्ण सलाह जो मैं दे सकता हूं वह है:
सलाह # 1 सुनिश्चित करें कि आपके स्रोत कोड में शामिल निर्माण चरण डॉकफाइल में जितनी देर हो सके उतनी देर से आए और एक &&या एक का उपयोग करके पिछले कमांड से बंधे न हों ;।
इसका कारण यह है कि पिछले सभी चरणों को कैश किया जाएगा और संबंधित परतों को बार-बार डाउनलोड करने की आवश्यकता नहीं होगी। इसका मतलब है तेजी से निर्माण और तेजी से रिलीज, जो शायद आप चाहते हैं। दिलचस्प रूप से पर्याप्त है, डॉकटर कैश का इष्टतम उपयोग करना आश्चर्यजनक रूप से कठिन है।
मेरी दूसरी सलाह कम महत्वपूर्ण है लेकिन मैं इसे रखरखाव के दृष्टिकोण से बहुत उपयोगी मानता हूं:
सलाह # 2 डॉकरफाइल में जटिल कमांड न लिखें , बल्कि उन स्क्रिप्ट का उपयोग करें जिन्हें कॉपी और निष्पादित किया जाना है।
इस सलाह का पालन करने वाला डॉकरफाइल जैसा लगेगा
COPY apt_setup.sh /root/
RUN sh -x /root/apt_setup.sh
COPY install_pacakges.sh /root/
RUN sh -x /root/install_packages.sh
और इसी तरह। कई आदेशों को बाध्य करने की सलाह &&में केवल एक सीमित गुंजाइश है। स्क्रिप्ट के साथ लिखना बहुत आसान है, जहां आप कार्यों का उपयोग कर सकते हैं, आदि अतिरेक से बचने के लिए या प्रलेखन उद्देश्यों के लिए।
प्री-प्रोसेसर से दिलचस्पी रखने वाले लोग COPYऔर कदमों के कारण होने वाले छोटे ओवरहेड से बचने के लिए तैयार रहते हैं और वास्तव में एक डॉकरफाइल को ऑन-द-फ्लाई करते हैं जहां
COPY apt_setup.sh /root/
RUN sh -x /root/apt_setup.sh
अनुक्रमों द्वारा प्रतिस्थापित किया जाता है
RUN base64 --decode … | sh -x
जहां का आधार …64-एन्कोडेड संस्करण है apt_setup.sh।
मेरी तीसरी सलाह उन लोगों के लिए है जो आकार और परतों की संख्या को लंबे समय तक बनाए रखना चाहते हैं।
सलाह # 3with मध्यवर्ती परतों में मौजूद फाइलों से बचने के लिए -idiom का उपयोग करें लेकिन परिणामी फाइलसिस्टम में नहीं।
कुछ डॉकटर अनुदेश द्वारा जोड़ी गई फ़ाइल और कुछ बाद के निर्देश द्वारा हटा दी गई परिणामी फाइलसिस्टम में मौजूद नहीं है, लेकिन इसका उल्लेख डॉक लेयर्स में दो बार किया गया है, जो निर्माण में डॉक छवि बनाते हैं। एक बार, नाम और पूरी सामग्री के साथ परत में, अनुदेश जोड़ने के परिणामस्वरूप, और एक बार परत में एक विलोपन नोटिस के रूप में निर्देश के परिणामस्वरूप।
उदाहरण के लिए, मान लें कि हमें अस्थायी रूप से C कंपाइलर और कुछ छवि की आवश्यकता है और विचार करें
# !!! THIS DISPLAYS SOME PROBLEM --- DO NOT USE !!!
RUN apt-get install -y gcc
RUN gcc --version
RUN apt-get --purge autoremove -y gcc
(अधिक यथार्थवादी उदाहरण केवल --versionध्वज के साथ अपनी उपस्थिति का दावा करने के बजाय संकलक के साथ कुछ सॉफ़्टवेयर का निर्माण करेगा ।)
Dockerfile स्निपेट तीन परतें बनाता है, पहले वाले में पूर्ण gcc सूट होता है, भले ही वह अंतिम फाइल सिस्टम में मौजूद न हो, लेकिन संबंधित डेटा अभी भी उसी तरह से छवि का हिस्सा है और जब भी डाउनलोड, अपलोड और अनसुना करने की आवश्यकता होती है अंतिम छवि है
with-Idiom अलग संसाधन स्वामित्व और संसाधन इसे प्रयोग तर्क से रिहा करने के लिए कार्यात्मक प्रोग्रामिंग में एक आम रूप है। इस मुहावरे को शेल-स्क्रिप्टिंग में स्थानांतरित करना आसान है, और हम पिछली स्क्रिप्ट को निम्नलिखित स्क्रिप्ट के रूप में फिर से लागू कर सकते हैं, COPY & RUNजैसा कि सलाह # 2 में इस्तेमाल किया जा सकता है ।
# with_c_compiler SIMPLE-COMMAND
# Execute SIMPLE-COMMAND in a sub-shell with gcc being available.
with_c_compiler()
(
set -e
apt-get install -y gcc
"$@"
trap 'apt-get --purge autoremove -y gcc' EXIT
)
with_c_compiler\
gcc --version
कॉम्प्लेक्स कमांड को फ़ंक्शन में बदल दिया जा सकता है ताकि उन्हें खिलाया जा सके with_c_compiler। यह कई with_whateverकार्यों के कॉल की श्रृंखला के लिए भी संभव है , लेकिन शायद बहुत वांछनीय नहीं है। (शेल की अधिक गूढ़ विशेषताओं का उपयोग करके, निश्चित रूप से with_c_compilerजटिल कमांड को बनाना संभव है , लेकिन इन जटिल कमांड्स को फ़ंक्शन में लपेटने के लिए यह सभी पहलुओं में बेहतर है।)
अगर हम सलाह # 2 को नजरअंदाज करना चाहते हैं, तो परिणामस्वरूप डॉकरीफाइल स्निपेट होगा
RUN apt-get install -y gcc\
&& gcc --version\
&& apt-get --purge autoremove -y gcc
जो ओफिसकेशन के कारण पढ़ना और बनाए रखना इतना आसान नहीं है। देखें कि शेल-स्क्रिप्ट संस्करण किस प्रकार महत्वपूर्ण भाग पर जोर देता है gcc --versionजबकि जंजीर- &&संस्करण शोर के बीच में उस हिस्से को दबा देता है।