डॉकरफाइल में "वोल्यूम" निर्देश को समझना


136

नीचे मेरी "डॉकरीफ़ाइल" की सामग्री है

FROM node:boron

# Create app directory
RUN mkdir -p /usr/src/app

# change working dir to /usr/src/app
WORKDIR /usr/src/app

VOLUME . /usr/src/app

RUN npm install

EXPOSE 8080

CMD ["node" , "server" ]

इस फ़ाइल में मैं "VOLUME। / Usr / src / app" निर्देश की उम्मीद कर रहा हूं कि मेजबान में वर्तमान कार्यशील निर्देशिका की सामग्री को माउंट करने के लिए / usr / src / app फ़ोल्डर पर माउंट किया जाए।

कृपया मुझे बताएं कि क्या यह सही तरीका है?

जवाबों:


88

आधिकारिक docker ट्यूटोरियल कहता है:

एक डेटा वॉल्यूम एक या अधिक कंटेनरों के भीतर एक विशेष रूप से निर्दिष्ट निर्देशिका है जो यूनियन फाइल सिस्टम को बायपास करता है। डेटा वॉल्यूम लगातार या साझा किए गए डेटा के लिए कई उपयोगी सुविधाएँ प्रदान करते हैं:

  • कंटेनर बनाए जाने पर वॉल्यूम को इनिशियलाइज़ किया जाता है। यदि कंटेनर की आधार छवि में निर्दिष्ट माउंट बिंदु पर डेटा शामिल है,
    तो मौजूदा डेटा को वॉल्यूम
    आरंभीकरण पर नए वॉल्यूम में कॉपी किया जाता है। (ध्यान दें कि होस्ट
    निर्देशिका बढ़ते समय यह लागू नहीं होता है ।)
  • डेटा वॉल्यूम को कंटेनरों के बीच साझा और पुन: उपयोग किया जा सकता है।

  • डेटा वॉल्यूम में परिवर्तन सीधे किए जाते हैं।

  • जब आप किसी छवि को अपडेट करते हैं तो डेटा वॉल्यूम में परिवर्तन शामिल नहीं किया जाएगा।

  • डेटा वॉल्यूम तब भी बने रहते हैं, जब कंटेनर स्वयं हटा दिया जाता है।

में Dockerfileआप केवल एक मात्रा का गंतव्य निर्दिष्ट कर सकते हैं अंदर एक कंटेनर। उदा /usr/src/app

जब आप एक कंटेनर चलाते हैं, उदाहरण के लिए docker run --volume=/opt:/usr/src/app my_image, आप होस्ट मशीन पर इसके बढ़ते बिंदु ( / ऑप्ट ) को निर्दिष्ट नहीं कर सकते हैं । यदि आप --volumeतर्क निर्दिष्ट नहीं करते हैं, तो माउंट बिंदु को स्वचालित रूप से चुना जाएगा, आमतौर पर नीचे /var/lib/docker/volumes/


275

संक्षेप में: नहीं, आपका VOLUMEनिर्देश सही नहीं है।

डॉकरीफाइल VOLUMEनिर्दिष्ट कंटेनर साइड वाले एक या अधिक संस्करणों को निर्दिष्ट करता है। लेकिन यह छवि लेखक को होस्ट पथ निर्दिष्ट करने की अनुमति नहीं देता है। होस्ट-साइड पर, डॉकर रूट के अंदर एक बहुत लंबे आईडी जैसे नाम के साथ वॉल्यूम बनाए जाते हैं। मेरी मशीन पर यह है /var/lib/docker/volumes

नोट: क्योंकि ऑटोजेनरेटेड नाम बहुत लंबा है और मानव के दृष्टिकोण से कोई मतलब नहीं है, इसलिए इन संस्करणों को अक्सर "अनाम" या "अनाम" कहा जाता है।

आपका उदाहरण जो 'का उपयोग करता है।' चरित्र मेरी मशीन पर भी नहीं चलेगा, चाहे मैं डॉट को पहला या दूसरा तर्क बनाऊं। मुझे यह त्रुटि संदेश मिला:

docker: डेमन से त्रुटि प्रतिक्रिया: oci रनटाइम त्रुटि: container_linux.go: 265: कंटेनर प्रक्रिया शुरू करने का कारण "process_linux.go: 368: कंटेनर इनट के कारण \" ओपन / डेव / ptmx: ऐसा कोई फ़ाइल या "निर्देशिका" नहीं है।

मुझे पता है कि क्या इस मुद्दे पर कहा गया है शायद किसी को समझने की कोशिश कर के लिए बहुत मूल्यवान नहीं है VOLUMEऔर -vऔर यह निश्चित रूप से आप क्या हासिल करने की कोशिश के लिए एक समाधान प्रदान नहीं करता है। तो, उम्मीद है, निम्नलिखित उदाहरण इन मुद्दों पर कुछ और प्रकाश डालेंगे।

न्यूनतम: वॉल्यूम निर्दिष्ट करना

इस डॉकरफाइल को देखते हुए:

FROM openjdk:8u131-jdk-alpine
VOLUME vol1 vol2

(यदि हम निर्दिष्ट करते हैं vol1 vol2या /vol1 /vol2क्यों नहीं करते हैं , तो इस मिनिस्टीरियल के परिणाम से कोई फर्क नहीं पड़ता )

इसे बनाओ:

docker build -t my-openjdk

Daud:

docker run --rm -it my-openjdk

कंटेनर के अंदर, lsकमांड लाइन में चलाएं और आप देखेंगे कि दो निर्देशिकाएं मौजूद हैं; /vol1और /vol2

कंटेनर को चलाने से मेजबान की तरफ दो निर्देशिकाएं या "वॉल्यूम" भी बनते हैं।

कंटेनर चल रहा है, मेजबान मशीनdocker volume ls पर निष्पादित करें और आपको कुछ इस तरह दिखाई देगा (मैंने नाम के मध्य भाग को तीन डॉट के साथ संक्षिप्तता के लिए बदल दिया है):

DRIVER    VOLUME NAME
local     c984...e4fc
local     f670...49f0

वापस कंटेनर में , निष्पादित करें touch /vol1/weird-ass-file(उक्त स्थान पर एक रिक्त फ़ाइल बनाता है)।

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

sudo ls /var/lib/docker/volumes/f670...49f0/_data

इसी तरह, आप होस्ट पर इस फ़ाइल को हटाने का प्रयास कर सकते हैं और इसे कंटेनर में भी हटा दिया जाएगा।

नोट: _dataफ़ोल्डर को "माउंट बिंदु" के रूप में भी संदर्भित किया जाता है।

कंटेनर से बाहर निकलें और होस्ट पर वॉल्यूम को सूचीबद्ध करें। वे चले गए हैं। हमने --rmकंटेनर चलाते समय ध्वज का उपयोग किया था और यह विकल्प प्रभावी रूप से न केवल कंटेनर को बाहर निकलने पर मिटा देता है, बल्कि वॉल्यूम भी।

एक नया कंटेनर चलाएं, लेकिन एक मात्रा का उपयोग करके निर्दिष्ट करें -v:

docker run --rm -it -v /vol3 my-openjdk

यह एक तीसरा वॉल्यूम जोड़ता है और पूरे सिस्टम में तीन अनाम वॉल्यूम होते हैं। कमांड क्रैश हो गया होगा हम केवल निर्दिष्ट किया था -v vol3। तर्क कंटेनर के अंदर एक पूर्ण पथ होना चाहिए । होस्ट-साइड पर, नया तीसरा वॉल्यूम गुमनाम है और अन्य दो संस्करणों के साथ रहता है ।/var/lib/docker/volumes/

यह पहले कहा गया था कि Dockerfileएक होस्ट पथ पर मैप नहीं किया जा सकता है, जो रनटाइम के दौरान होस्ट से कंटेनर में फाइल लाने की कोशिश करते समय हमारे लिए एक समस्या पैदा करता है। एक अलग -vसिंटैक्स इस समस्या को हल करता है।

कल्पना कीजिए ./srcकि मेरी परियोजना निर्देशिका में एक सबफ़ोल्डर है जिसे मैं /srcकंटेनर के अंदर सिंक करना चाहता हूं । यह आदेश चाल करता है:

docker run -it -v $(pwd)/src:/src my-openjdk

:चरित्र के दोनों पक्षों को एक पूर्ण मार्ग की उम्मीद है। बाईं ओर मेजबान मशीन पर एक निरपेक्ष पथ है, दाएं तरफ कंटेनर के अंदर एक पूर्ण पथ है। pwdएक कमांड है जो "वर्तमान / कार्यशील निर्देशिका को प्रिंट करता है"। $()कोष्ठक के भीतर कमान ले जाने में कमांड डालते हुए , इसे एक उप-भाग में चलाता है और हमारी परियोजना निर्देशिका के लिए निरपेक्ष पथ को वापस लाता है।

यह सब एक साथ रखते हुए, मान लें कि ./src/Hello.javaहमारे प्रोजेक्ट फ़ोल्डर में हमारे पास मेजबान मशीन पर निम्नलिखित सामग्री है:

public class Hello {
    public static void main(String... ignored) {
        System.out.println("Hello, World!");
    }
}

हम इस Dockerfile का निर्माण करते हैं:

FROM openjdk:8u131-jdk-alpine
WORKDIR /src
ENTRYPOINT javac Hello.java && java Hello

हम यह आदेश चलाते हैं:

docker run -v $(pwd)/src:/src my-openjdk

यह प्रिंट "हैलो, वर्ल्ड!"।

सबसे अच्छी बात यह है कि हम .java फ़ाइल को संशोधित करने के लिए पूरी तरह से स्वतंत्र हैं। दूसरे रन पर एक और आउटपुट के लिए एक नए संदेश के साथ - छवि के पुनर्निर्माण के बिना =)

अंतिम टिप्पणी

मैं डॉकटर के लिए काफी नया हूं, और उपरोक्त "ट्यूटोरियल" एक 3-दिन कमांड लाइन हैकॉन से एकत्रित जानकारी को दर्शाता है। मुझे लगभग शर्म आती है कि मैं अपने बयानों के समर्थन में अंग्रेजी जैसे दस्तावेज को साफ करने के लिए लिंक प्रदान करने में सक्षम नहीं हूं, लेकिन मुझे ईमानदारी से लगता है कि यह दस्तावेज की कमी और व्यक्तिगत प्रयास के कारण है। मुझे पता है कि उदाहरण मेरे वर्तमान सेटअप का उपयोग करके विज्ञापन के रूप में काम करते हैं जो "विंडोज 10 -> वैग्रांट 2.0.0 -> डॉकर 17.09.0-सीई" है।

ट्यूटोरियल इस समस्या को हल नहीं करता है कि "हम डॉकरफाइल में कंटेनर के पथ को कैसे निर्दिष्ट करें और रन कमांड को केवल होस्ट पथ निर्दिष्ट करें"। एक रास्ता हो सकता है, मुझे अभी नहीं मिला है।

अंत में, मुझे यह महसूस हो रहा है कि VOLUMEडॉकफाइल में निर्दिष्ट करना केवल असामान्य नहीं है, लेकिन यह शायद कभी उपयोग नहीं करने के लिए सबसे अच्छा अभ्यास है VOLUME। दो कारणों से। पहला कारण जो हमने पहले ही पहचान लिया है: हम मेजबान पथ को निर्दिष्ट नहीं कर सकते हैं - जो कि एक अच्छी बात है क्योंकि डॉकएफ़ाइल्स एक मेजबान मशीन की बारीकियों के लिए बहुत ही अज्ञेय होना चाहिए। लेकिन दूसरा कारण यह है कि लोग --rmकंटेनर चलाते समय विकल्प का उपयोग करना भूल सकते हैं । एक कंटेनर को हटाने के लिए याद कर सकते हैं लेकिन मात्रा को हटाने के लिए भूल जाते हैं। इसके अलावा, यहां तक ​​कि सबसे अच्छी मानव स्मृति के साथ, यह पता लगाना एक कठिन काम हो सकता है कि सभी अनाम संस्करणों में से कौन सा सुरक्षित है।


2
हमें अनाम / अनाम संस्करणों का उपयोग कब करना चाहिए?
सेरेने

10
@Martin आपका बहुत-बहुत धन्यवाद। आपका हैकाथॉन और इसके परिणामी ट्यूटोरियल यहाँ बहुत आशंकित हैं।
बीजर

6
"मैं अंग्रेजी जैसे दस्तावेज़ को साफ़ करने के लिए लिंक प्रदान करने में सक्षम नहीं हुआ हूँ ... मुझे ईमानदारी से लगता है कि यह प्रलेखन की कमी के कारण है"। मैं पुष्टि कर सकता हूं। यह सबसे गहन और अद्यतित दस्तावेज है जो मैंने पाया है और मैं घंटों से देख रहा हूं।
user697576

4
docker volume pruneबचे हुए संस्करणों को साफ करने के लिए इस्तेमाल किया जा सकता है जो चल रहे कंटेनरों से जुड़े नहीं हैं। यह कहना आसान नहीं होगा कि अकेले आईडी द्वारा महत्वपूर्ण लोगों को परेशान करना आसान होगा ...
जेरेमी

4
"इस मिनिफायोरियल के परिणाम के लिए, यह कोई फर्क नहीं पड़ता है अगर हम vol1 vol2 या / vol1 / vol2 निर्दिष्ट करते हैं - मुझसे मत पूछें"। @MartinAndersson ऐसा इसलिए है क्योंकि वर्तमान वर्किंग डायरेक्टरी है /, इसलिए vol1सापेक्ष है /, जो इसका समाधान करता है /vol1। यदि आप इसके अलावा WORKDIRकिसी अन्य कार्यशील निर्देशिका को निर्दिष्ट करने के लिए उपयोग करते हैं /, vol1और /vol1अब उसी निर्देशिका को इंगित नहीं करेगा।
सेबस्टियन

41

VOLUMEDockerfile में एक पंक्ति निर्दिष्ट करना आपकी छवि पर मेटाडेटा का एक सा कॉन्फ़िगर करता है, लेकिन मेटाडेटा का उपयोग कैसे किया जाता है यह महत्वपूर्ण है।

पहले, इन दो लाइनों ने क्या किया:

WORKDIR /usr/src/app
VOLUME . /usr/src/app

WORKDIRलाइन अगर यह मौजूद नहीं है वहाँ निर्देशिका बनाता है, और इस तरह के आदेश के लिए वर्तमान निर्देशिका के साथ-साथ सभी संबंधित पथ निर्दिष्ट करने के लिए कुछ छवि मेटाडाटा को अद्यतन करता RUNहै कि स्थान में हो जाएगा। VOLUMEवहां की रेखा दो संस्करणों को निर्दिष्ट करती है , एक सापेक्ष पथ है ., और दूसरा है /usr/src/app, दोनों बस एक ही निर्देशिका के होते हैं। ज्यादातर अक्सर VOLUMEलाइन में केवल एक ही डायरेक्टरी होती है, लेकिन इसमें मल्टीपल हो सकता है जैसा कि आपने किया है, या यह एक फॉर्मूलाबद्ध ऐरेसन हो सकता है।

आप Dockerfile में वॉल्यूम स्रोत निर्दिष्ट नहीं कर सकते हैं : जब Dockerfile में वॉल्यूम निर्दिष्ट किया जाता है तो भ्रम का एक सामान्य स्रोत छवि बिल्ड समय पर किसी स्रोत और गंतव्य के रनटाइम सिंटैक्स से मिलान करने का प्रयास कर रहा है, यह काम नहीं करेगा । Dockerfile केवल वॉल्यूम के गंतव्य को निर्दिष्ट कर सकता है। यह एक तुच्छ सुरक्षा शोषण होगा यदि कोई वॉल्यूम के स्रोत को परिभाषित कर सकता है क्योंकि वे डॉकटर हब पर एक सामान्य छवि को कंटेनर में रूट करने के लिए अपडेट कर सकते हैं और फिर एक एंट्रीपॉइंट के हिस्से के रूप में कंटेनर के अंदर एक पृष्ठभूमि प्रक्रिया शुरू कर सकते हैं जो अगले रिबूट पर एक बिटकॉइन माइनर लॉन्च करने के लिए लॉगिन / / etc / passwd में सिस्टम को कॉन्फ़िगर करता है, या किसी दूरस्थ साइट पर भेजने के लिए क्रेडिट कार्ड, SSN, और निजी कुंजी के लिए फाइल सिस्टम की खोज करता है।

वोल्यूम लाइन क्या करती है? जैसा कि उल्लेख किया गया है, यह छवि के अंदर एक निर्देशिका कहने के लिए कुछ छवि मेटाडेटा सेट करता है। इस मेटाडेटा का उपयोग कैसे किया जाता है? हर बार जब आप इस छवि से एक कंटेनर बनाते हैं, तो docker उस निर्देशिका को वॉल्यूम के लिए मजबूर कर देगा। यदि आप अपने रन कमांड में एक वॉल्यूम प्रदान नहीं करते हैं, या फ़ाइल की रचना करते हैं, तो डॉक करने वाले के लिए एकमात्र विकल्प एक गुमनाम वॉल्यूम बनाना है। यह नाम के लिए एक लंबी अनूठी आईडी के साथ एक स्थानीय नामित वॉल्यूम है और इसे क्यों बनाया गया था या क्या डेटा शामिल है इसके लिए कोई अन्य संकेत नहीं है (अनाम वॉल्यूम थे डेटा खो जाने के लिए जाता है)। यदि आप एक नामित या होस्ट वॉल्यूम की ओर इशारा करते हुए वॉल्यूम को ओवरराइड करते हैं, तो आपका डेटा इसके बजाय वहां जाएगा।

वोल्यूम चीजों को तोड़ता है: आप एक डॉकफाइल में परिभाषित वॉल्यूम को एक बार अक्षम नहीं कर सकते। और इससे भी महत्वपूर्ण बात यह है RUNकि डॉक में आदेश अस्थायी कंटेनरों के साथ लागू किया जाता है। उन अस्थायी कंटेनरों को एक अस्थायी बेनामी वॉल्यूम मिलेगा। उस अनाम वॉल्यूम को आपकी छवि की सामग्री के साथ आरंभ किया जाएगा। आपके RUNकमांड से कंटेनर के अंदर कोई भी लिखता है जो उस वॉल्यूम के लिए बनाया जाएगा। जब RUNआदेश पूरा हो जाता है, तो छवि में परिवर्तन सहेजे जाते हैं, और अनाम वॉल्यूम में परिवर्तन छोड़ दिया जाता है। इस वजह से, मैं VOLUMEडॉकफाइल के अंदर को परिभाषित करने के खिलाफ दृढ़ता से सलाह देता हूं। यह आपकी छवि के डाउनस्ट्रीम उपयोगकर्ताओं के लिए अप्रत्याशित व्यवहार का परिणाम है जो वॉल्यूम स्थान में प्रारंभिक डेटा के साथ छवि का विस्तार करना चाहते हैं।

आपको एक वॉल्यूम कैसे निर्दिष्ट करना चाहिए? यह निर्दिष्ट करने के लिए कि आप अपनी छवि के साथ वॉल्यूम कहाँ शामिल करना चाहते हैं, एक प्रदान करें docker-compose.yml। उपयोगकर्ता अपने स्थानीय परिवेश में वॉल्यूम स्थान को समायोजित करने के लिए इसे संशोधित कर सकते हैं, और यह अन्य रनटाइम सेटिंग्स जैसे प्रकाशन पोर्ट और नेटवर्किंग को कैप्चर करता है।

किसी को यह दस्तावेज चाहिए! उनके पास है। Docker में Dockerfile पर अपने दस्तावेज़ में VOLUME उपयोग पर चेतावनी के साथ-साथ स्रोत को निर्दिष्ट करने की सलाह भी शामिल है:

  • Dockerfile के भीतर से वॉल्यूम बदलना: यदि कोई बिल्ड चरण घोषित किए जाने के बाद वॉल्यूम के भीतर डेटा को बदलता है, तो उन परिवर्तनों को छोड़ दिया जाएगा।

...

  • होस्ट निर्देशिका को कंटेनर रन-टाइम पर घोषित किया जाता है: होस्ट निर्देशिका (माउंटपॉइंट), इसकी प्रकृति, मेजबान-निर्भर है। यह छवि पोर्टेबिलिटी को संरक्षित करने के लिए है, क्योंकि किसी होस्ट होस्ट को सभी मेजबानों पर उपलब्ध होने की गारंटी नहीं दी जा सकती है। इस कारण से, आप Dockerfile के भीतर से होस्ट निर्देशिका माउंट नहीं कर सकते। VOLUME अनुदेश एक निर्दिष्ट करने का समर्थन नहीं करता host-dirपैरामीटर। जब आप कंटेनर बनाते हैं या चलाते हैं, तो आपको माउंट पॉइंट निर्दिष्ट करना चाहिए।

36

इसमें VOLUMEकमांड Dockerfileकाफी वैध है, पूरी तरह से पारंपरिक है, उपयोग करने के लिए बिल्कुल ठीक है और यह वैसे भी अपवित्र नहीं है। बस इसे समझने की जरूरत है।

हम इसका उपयोग किसी भी निर्देशिका को इंगित करने के लिए करते हैं जो कंटेनर में ऐप बहुत कुछ लिखेगा। हम VOLUMEसिर्फ इसलिए उपयोग नहीं करते हैं क्योंकि हम एक कॉन्फ़िगर फ़ाइल की तरह होस्ट और कंटेनर के बीच साझा करना चाहते हैं।

कमांड को बस एक परम की जरूरत है; WORKDIRकंटेनर के भीतर से, यदि सेट के सापेक्ष एक फ़ोल्डर का पथ । फिर docker अपने ग्राफ (/ var / lib / docker) में एक वॉल्यूम बनाएगा और कंटेनर में फ़ोल्डर में माउंट करेगा। अब कंटेनर को उच्च प्रदर्शन के साथ लिखना होगा। VOLUMEकमांड के बिना निर्दिष्ट फ़ोल्डर में लिखने की गति बहुत धीमी होगी क्योंकि अब कंटेनर copy on writeकंटेनर में ही रणनीति का उपयोग कर रहा है। copy on writeरणनीति एक मुख्य कारण मात्रा मौजूद है।

यदि आप VOLUMEकमांड द्वारा निर्दिष्ट फ़ोल्डर पर माउंट करते हैं , तो कमांड कभी नहीं चलाया जाता है क्योंकि VOLUMEकेवल कंटेनर शुरू होने पर निष्पादित किया जाता है, इस तरह का ENV

मूल रूप से VOLUMEकमांड के साथ आपको बाहरी किसी भी वॉल्यूम को बढ़ाए बिना प्रदर्शन मिलता है। डेटा किसी भी बाहरी माउंट के बिना कंटेनर रनों से भी बचाएगा। फिर जब तैयार हो तो बस उस पर कुछ चढ़ाएं।

कुछ अच्छे उदाहरण मामलों का उपयोग करते हैं:
- लॉग
- अस्थायी फ़ोल्डर

कुछ खराब उपयोग के मामले:
- स्थिर फाइलें
- कॉन्फिग
- कोड


2
अच्छे और बुरे उदाहरण के उपयोग के मामलों के बारे में, डॉकर के "dockerfile बेस्ट-प्रैक्टिस" पृष्ठ कहता है: "आपको अपनी छवि के किसी भी परिवर्तनशील और / या उपयोगकर्ता-सेवा योग्य भागों के लिए VOLUME का उपयोग करने के लिए दृढ़ता से प्रोत्साहित किया जाता है।" मुझे लगता है कि विन्यास में हैं।
ओमेरस्क

2
यह VOLUMEविन्यास के लिए dirs के बारे में स्पष्ट होना ठीक है । हालाँकि एक बार जब आप वास्तव में एक कॉन्फ़िगरेशन को माउंट करते हैं तो आपको उस निर्देशिका पर माउंट करना होगा और इसलिए VOLUMEकमांड नहीं चलता है। इसलिए यह VOLUMEएक विन्यास के लिए निर्दिष्ट dir पर कमांड का उपयोग करने के लिए व्यर्थ है । एक एकल स्थिर रीड ओनली फाइल के साथ वॉल्यूम ग्राफ को इनिशियलाइज़ करना गंभीर ओवरकिल है। इसलिए मैंने जो कहा, मैं उसके साथ खड़ा हूं, VOLUMEकॉन्फिग पर कमांड की जरूरत नहीं है ।
मृग

कार्यान्वयन विस्तार के कारण वॉल्यूम विभिन्न प्रदर्शन विशेषताओं को ला सकते हैं। डेटाबेस डेटा फाइलें इस उपयोग के मामले में फिट हैं, लेकिन वैसे भी (पंचांग) कंटेनर स्टोरेज के साथ डेटा को स्टोर करने का क्या मतलब होगा? प्रदर्शन के लिए वॉल्यूम के अस्तित्व को जिम्मेदार ठहराना गलत है।
एंड्रे वेरलैंग

33

volumeDockerfile में निर्देश को बेहतर ढंग से समझने के लिए , आइए हम mysql के आधिकारिक docker फ़ाइल कार्यान्वयन में विशिष्ट मात्रा उपयोग सीखें।

VOLUME /var/lib/mysql

संदर्भ: https://github.com/docker-library/mysql/blob/3362baccb4352bcf0022014f67c1ec7e6808b8c5/8.0-Dockerfile

/var/lib/mysqlMySQL के डिफ़ॉल्ट स्थान है कि दुकान डेटा फ़ाइलों है।

जब आप केवल परीक्षण उद्देश्य के लिए परीक्षण कंटेनर चलाते हैं, तो आप इसके बढ़ते बिंदु को निर्दिष्ट नहीं कर सकते हैं, उदाहरण के लिए

docker run mysql:8

तब mysql कंटेनर आवृत्ति डिफ़ॉल्ट माउंट पथ का उपयोग करेगी जो volumeडॉकटरफाइल में निर्देश द्वारा निर्दिष्ट है । वॉल्यूम को डॉकर रूट के अंदर बहुत लंबे आईडी जैसे नाम के साथ बनाया जाता है, इसे "अनाम" या "अनाम" वॉल्यूम कहा जाता है। अंतर्निहित होस्ट सिस्टम / var / lib / docker / संस्करणों के फ़ोल्डर में।

/var/lib/docker/volumes/320752e0e70d1590e905b02d484c22689e69adcbd764a69e39b17bc330b984e4

बढ़ते बिंदु को निर्दिष्ट करने की आवश्यकता के बिना त्वरित परीक्षण उद्देश्यों के लिए यह बहुत सुविधाजनक है, लेकिन फिर भी डेटा स्टोर के लिए वॉल्यूम का उपयोग करके सर्वश्रेष्ठ प्रदर्शन प्राप्त कर सकते हैं, न कि कंटेनर परत।

एक औपचारिक उपयोग के लिए, आपको नामित पथ या बाइंड माउंट का उपयोग करके माउंट पथ निर्दिष्ट करना होगा, उदा

docker run  -v /my/own/datadir:/var/lib/mysql mysql:8

आदेश अंतर्निहित होस्ट सिस्टम से / my / खुद / datadir निर्देशिका को कंटेनर के अंदर / var / lib / mysql के रूप में गिनता है। डेटा निर्देशिका / my / खुद / datadir स्वचालित रूप से नष्ट नहीं होगा, यहां तक ​​कि कंटेनर को भी हटा दिया जाता है।

Mysql आधिकारिक छवि का उपयोग (कृपया "डेटा कहाँ स्टोर करें" अनुभाग देखें):

संदर्भ: https://hub.docker.com/_/mysql/


2
मुझे तुम्हारा स्पष्टीकरण बहुत पसंद है।
लुकसजटार्स्का 9

लेकिन docker वैसे भी परिवर्तनों को सहेजता है। इसके अलावा आप -vDockerfile
Alex78191

1

मैं किसी भी मामले में VOLUME के ​​उपयोग को अच्छा नहीं मानता, सिवाय इसके कि आप अपने लिए एक छवि बना रहे हैं और कोई और इसका उपयोग करने वाला नहीं है।

आधार छवियों में वोल्यूम के कारण मैं नकारात्मक रूप से प्रभावित हुआ, जो मैंने बढ़ाया और केवल छवि के पहले से ही चलने के बाद समस्या के बारे में पता चला, जैसे कि वर्डप्रेस जो /var/www/htmlफ़ोल्डर को वीओएलएमई घोषित करता है , और इसका मतलब यह था कि किसी भी फाइल या दौरान बदल गया है बिल्ड स्टेज पर विचार नहीं किया जाता है, और लाइव परिवर्तन जारी रहता है, भले ही आपको पता न हो। किसी अन्य स्थान पर वेब निर्देशिका को परिभाषित करने के लिए एक बदसूरत वर्कअराउंड है, लेकिन यह केवल एक को सरल करने के लिए एक बुरा समाधान है: बस वोल्यूम निर्देश को हटा दें।

आप -vविकल्प का उपयोग करके आसानी से वॉल्यूम की मंशा प्राप्त कर सकते हैं , इससे न केवल यह स्पष्ट हो जाएगा कि कंटेनर की मात्रा क्या होगी (डॉकरफाइल और माता-पिता डॉकरीफाइल्स पर एक नज़र डालने के बिना), लेकिन यह भी उपभोक्ता को विकल्प देता है वॉल्यूम का उपयोग करें या नहीं।

इस उत्तर के अनुसार, निम्नलिखित कारणों से वीओएलईएमईएस का उपयोग करना मूल रूप से बुरा है :

हालाँकि, VOLUME निर्देश लागत पर आता है।

  • हो सकता है कि उपयोगकर्ता अनाम वॉल्यूम के बनाए जाने के बारे में नहीं जानते हों, और कंटेनरों को हटाए जाने के बाद अपने डॉकर होस्ट पर स्टोरेज स्पेस लेना जारी रखें।
  • डॉकरफाइल में घोषित मात्रा को हटाने का कोई तरीका नहीं है। डाउनस्ट्रीम छवियां उन पथों में डेटा नहीं जोड़ सकती हैं जहां वॉल्यूम मौजूद हैं।

उत्तरार्द्ध मुद्दा इन जैसी समस्याओं का परिणाम है।

वॉल्यूम को पूर्ववत् करने का विकल्प होने से मदद मिलेगी, लेकिन केवल तभी जब आप डॉकटराइल में परिभाषित वॉल्यूम जानते हैं जो छवि उत्पन्न करता है (और अभिभावक dockerfiles!)। इसके अलावा, डॉकफाइल के नए संस्करणों में एक वोल्यूम जोड़ा जा सकता है और छवि के उपभोक्ताओं के लिए अप्रत्याशित रूप से चीजों को तोड़ सकता है।

एक और अच्छी व्याख्या ( जो VOLUME वाली ऑरेकल इमेज के बारे में , जिसे हटा दिया गया था ): https://github.com/oracle/docker-images/issues/640#issuecomment-412647328

अधिक मामले जिनमें VOLUME ने लोगों के लिए सामान तोड़ा:

पेरेंट इमेज (VOLUME सहित) को रीसेट करने के लिए विकल्पों को जोड़ने के लिए एक पुल अनुरोध , को बंद कर दिया गया था और यहां चर्चा की जा रही है (और आप doकरfiles में परिभाषित संस्करणों के कारण लोगों के प्रभावित होने के कई मामलों को देख सकते हैं ), जिसमें एक अच्छी टिप्पणी है वोल्यूम के खिलाफ स्पष्टीकरण:

Dockerfile में VOLUME का उपयोग करना बेकार है। यदि उपयोगकर्ता को दृढ़ता की आवश्यकता होती है, तो वे निर्दिष्ट कंटेनर को चलाते समय वॉल्यूम मैपिंग प्रदान करना सुनिश्चित करेंगे। यह ट्रैक करना बहुत कठिन था कि डायरेक्ट्री के स्वामित्व (/ var / lib / influxdb) को सेट करने में सक्षम नहीं होने का मेरा मुद्दा इन्फ्लेक्सडीबी के डॉकरफाइल में वोल्यूम घोषणा के कारण था। बिना UNVOLUME विकल्प के, या पूरी तरह से छुटकारा पाने के बाद, मैं निर्दिष्ट फ़ोल्डर से संबंधित कुछ भी बदलने में असमर्थ हूं। यह आदर्श से कम है, खासकर जब आप सुरक्षा-जागरूक होते हैं और एक निश्चित यूआईडी को निर्दिष्ट करने की इच्छा रखते हैं, जैसे कि एक यादृच्छिक उपयोगकर्ता से बचने के लिए, आपके होस्ट पर सॉफ़्टवेयर चलाने से अधिक अनुमतियों के साथ, छवि को चलाना चाहिए।

मैं EXPOSE को भी बुरा मानता हूं, लेकिन इसके दुष्प्रभाव कम हैं। एकमात्र अच्छी बात जो मैं वीओएलएमई और एक्सपो के बारे में देख सकता हूं वह प्रलेखन के बारे में है, और मैं उन्हें अच्छा मानूंगा यदि वे केवल उसी के लिए (बिना किसी दुष्प्रभाव के) सेवा करते हैं।

टी एल; डॉ

मेरा विचार है कि वीओएलएमई का सबसे अच्छा उपयोग किया जाना है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.