Docker माउंट: Volumes, Bind Mounts, और tmpfs समझाया गया
Docker माउंट्स, कंटेनरों को persistent स्टोरेज से तीन प्रकारों के माध्यम से जोड़ते हैं - प्रोडक्शन डेटा के लिए volumes, डेवलपमेंट वर्कफ़्लोज़ के लिए bind mounts, और अस्थायी फ़ाइलों के लिए tmpfs।
मान लीजिए आपने किसी कॉन्फ़िगरेशन फ़ाइल को अपडेट करने के लिए Docker कंटेनर रोका, लेकिन दोबारा शुरू करने पर सारा डेटा गायब था। मेरे साथ भी ऐसा हुआ है।
ऐसा इसलिए होता है क्योंकि कंटेनर डिफ़ॉल्ट रूप से ephemeral होते हैं – जब उन्हें हटाया जाता है, तो उनकी writable लेयर में संग्रहीत कोई भी डेटा गायब हो जाता है। वास्तविक एप्लिकेशन ऐसे नहीं चल सकते। आपको ऐसे डेटाबेस चाहिए जो बने रहें, ऐसे कॉन्फ़िग फ़ाइलें जो रीस्टार्ट के बाद भी बचीं रहें, और ऐसे लॉग जिन्हें आप वास्तव में एक्सेस कर सकें।
Docker माउंट इस समस्या को कंटेनर स्टोरेज को बाहरी लोकेशनों से जोड़कर हल करता है। इसके तीन प्रकार हैं: प्रोडक्शन डेटा के लिए volumes, डेवलपमेंट वर्कफ़्लो के लिए bind mounts, और tmpfs जो मेमोरी में अस्थायी फ़ाइलें रखता है।
इस लेख में, मैं आपको आपके उपयोग-केस के लिए सही माउंट प्रकार चुनने और उसे सही तरीके से लागू करने की प्रक्रिया समझाऊंगा। यहाँ कवर की गई हर बात समझने के लिए, आपको Docker और कंटेनराइज़ेशन की अच्छी समझ चाहिए। जल्दी गति पकड़ने के लिए हमारा Intermediate Docker कोर्स करें।
Docker स्टोरेज को कैसे संभालता है
Docker कंटेनर layered फ़ाइलसिस्टम का उपयोग करते हैं जो डिफ़ॉल्ट रूप से हर चीज़ को अस्थायी मानता है।
जब आप Docker इमेज बनाते हैं, तो आपके Dockerfile की हर इंस्ट्रक्शन एक नई read-only लेयर बनाती है। ये लेयरें एक-दूसरे के ऊपर कार्डों की गड्डी की तरह स्टैक होती हैं। यदि आप Python इंस्टॉल किए हुए Ubuntu इमेज को pull करते हैं, तो आपको बेस OS के लिए एक लेयर और Python के लिए दूसरी लेयर मिलेगी।
पेंच यह है कि ये सारी लेयरें read-only होती हैं। आप इन्हें संशोधित नहीं कर सकते।
कंटेनर फ़ाइलसिस्टम और writable लेयर
जब आप कंटेनर शुरू करते हैं, Docker सबसे ऊपर एक और लेयर जोड़ता है - writable कंटेनर लेयर।
सारी परिवर्तन यहीं होते हैं। आप जो भी फ़ाइल बनाते हैं, जो भी कॉन्फ़िग बदलते हैं, और जो भी टेबल रिकॉर्ड जोड़ते हैं, वह सब यहीं रहता है।
यह सुनने में अच्छा लगता है, लेकिन समस्या यह है कि यह लेयर कंटेनर के lifecycle से बंधी होती है।
जब आप docker rm से कंटेनर को रोककर हटा देते हैं, तो writable लेयर चली जाती है। आपने जो कुछ भी किया था, वह सब खत्म। Docker पुष्टि नहीं मांगता। यह बस सब कुछ हटा देता है।
यह डिज़ाइन stateless ऐप्स के लिए ठीक है जिन्हें रन के बीच कुछ याद नहीं रखना होता। लेकिन वास्तविक एप्लिकेशन stateless नहीं होते।
माउंट्स क्यों आवश्यक हैं
प्रोडक्शन वातावरण में writable लेयर के दो बड़े मुद्दे हैं।
पहला, कंटेनर रुकने पर आपका डेटा खो जाता है। किसी ऐसे डेटाबेस कंटेनर का क्या फ़ायदा जो रीस्टार्ट के बाद सभी rows भूल जाए? मेरे ख्याल से इसका उपयोग सिर्फ़ आपके ऐप के इंटीग्रेशन टेस्ट चलाने में ही हो सकता है।
दूसरा, आप कंटेनरों के बीच डेटा साझा नहीं कर सकते। मान लीजिए आप एक वेब ऐप और एक बैकग्राउंड वर्कर चला रहे हैं जिन्हें एक ही फ़ाइलों की जरूरत है। अगर वे फ़ाइलें किसी एक कंटेनर की writable लेयर में हैं, तो दूसरा कंटेनर उन्हें नहीं देख पाएगा।
Docker माउंट्स दोनों समस्याओं को हल करते हैं क्योंकि वे कंटेनरों को ऐसे स्टोरेज से जोड़ते हैं जो कंटेनर lifecycle से बाहर मौजूद होता है। आप अपने होस्ट मशीन से कोई डायरेक्टरी या Docker-प्रबंधित volume माउंट कर सकते हैं। कंटेनर हटाए जाने पर भी आपका डेटा बना रहता है। एक से अधिक कंटेनर एक ही लोकेशन को माउंट कर सकते हैं और वास्तविक समय में फ़ाइलें साझा कर सकते हैं।
इसीलिए आपको माउंट्स का उपयोग करना चाहिए। आगे हम माउंट प्रकारों पर नज़र डालेंगे, और फिर मैं दिखाऊंगा कि वे कैसे काम करते हैं।
Docker माउंट प्रकार एक नज़र में
Docker आपको persistent डेटा संभालने के तीन तरीके देता है, और प्रत्येक अलग समस्या हल करता है। यहाँ हर प्रकार क्या करता है और कब उपयोग करना चाहिए:
Volumes
Volumes, persistent स्टोरेज के लिए Docker का डिफ़ॉल्ट समाधान हैं।
Docker आपकी होस्ट मशीन पर एक समर्पित डायरेक्टरी में volumes बनाता और प्रबंधित करता है। आपको यह जानने की ज़रूरत नहीं कि वह डायरेक्टरी कहाँ है, सब कुछ Docker संभालता है। इससे volumes अलग-अलग सिस्टमों में पोर्टेबल रहते हैं और प्रोडक्शन में उपयोग के लिए सुरक्षित होते हैं।
जब आप कंटेनर हटाते हैं, तो volume जस का तस रहता है। यदि आप एक नया कंटेनर शुरू करके उसी volume को अटैच करते हैं, तो आपका सारा डेटा वहीं मिलेगा जहाँ आपने छोड़ा था।
Volumes प्रोडक्शन डेटाबेस, एप्लिकेशन स्टेट, और ऐसा कोई भी डेटा जिसके खोने का जोखिम आप नहीं उठा सकते, के लिए सबसे बेहतर हैं।
Bind mounts
Bind mounts आपकी होस्ट मशीन की किसी विशेष डायरेक्टरी को सीधे कंटेनर से जोड़ते हैं।
आप होस्ट पर सटीक पाथ चुनते हैं - जैसे /home/user/project - और Docker उसे कंटेनर में मैप कर देता है। जब आप होस्ट पर कोई फ़ाइल बदलते हैं, तो कंटेनर तुरंत बदलाव देखता है। कंटेनर में फ़ाइल बदलें, और वह आपके होस्ट पर दिखाई देगी।
यह रीयल-टाइम सिंक bind mounts को डेवलपमेंट के लिए बेहतरीन बनाता है।
लेकिन bind mounts के साथ जोखिम आते हैं। ये होस्ट पाथ्स को कंटेनरों के सामने खोलते हैं और ऐसी डायरेक्टरी संरचनाओं पर निर्भर रहते हैं जो अन्य मशीनों पर मौजूद न हों।
tmpfs माउंट्स
tmpfs माउंट्स डेटा को डिस्क के बजाय आपकी होस्ट की मेमोरी में स्टोर करते हैं।
फ़ाइलसिस्टम पर कुछ भी नहीं लिखा जाता। कंटेनर रुकते ही डेटा पूरी तरह गायब हो जाता है। इससे tmpfs माउंट्स अस्थायी डेटा जिसे आप स्थायी रखना नहीं चाहते के लिए उपयोगी बनते हैं - जैसे ऑथेंटिकेशन टोकन, सेशन डेटा, या कैश फ़ाइलें जिन्हें आप वैसे भी दोबारा बनाएंगे।
हालाँकि, tmpfs माउंट्स उपलब्ध RAM से सीमित होते हैं और केवल Linux होस्ट्स पर काम करते हैं।
Persistent डेटा के लिए Docker Volumes
Volumes Docker का प्रोडक्शन-रेडी स्टोरेज समाधान हैं, और आपको डिफ़ॉल्ट रूप से इन्हें ही उपयोग करना चाहिए जब तक कि न करने का कोई खास कारण न हो।
ये पूरी तरह Docker द्वारा प्रबंधित होते हैं, अलग-अलग प्लेटफ़ॉर्म पर समान रूप से काम करते हैं, और डिजाइन के हिसाब से कंटेनर हटाने के बाद भी बने रहते हैं। यदि आप डेटाबेस चला रहे हैं, एप्लिकेशन स्टेट स्टोर कर रहे हैं, या ऐसा कोई भी डेटा संभाल रहे हैं जिसे एक कंटेनर से अधिक समय तक जीवित रहना है, तो volumes ही समाधान हैं।
Docker volumes कैसे काम करते हैं
Docker आपकी होस्ट मशीन पर एक समर्पित डायरेक्टरी में volumes स्टोर करता है:
आप इस डायरेक्टरी को सीधे प्रबंधित नहीं करते। Docker अपनी API के ज़रिए निर्माण, परमिशन, और क्लीनअप संभालता है। यह अलगाव सुनिश्चित करता है कि Linux, Mac या Windows पर volumes एक ही तरह से काम करते हैं, जिससे आपका कंटेनर सेटअप डेवलपमेंट और प्रोडक्शन वातावरणों में पोर्टेबल बनता है।
यहाँ याद रखने वाली बात यह है कि volumes किसी भी कंटेनर से स्वतंत्र रूप से मौजूद रहते हैं। जब आप कोई volume बनाते हैं, उसे कंटेनर से जोड़ते हैं, ऐप चलाते हैं, फिर कंटेनर को रोककर हटा देते हैं, तब भी volume अपने स्थान पर और आपके सभी डेटा के साथ बना रहता है।
यदि आप नया कंटेनर शुरू करके वही volume अटैच करते हैं, तो आपका डेटा वहीं मिलेगा।
Volumes बनाना और पुन: उपयोग करना
आप किसी भी कंटेनर को शुरू करने से पहले एक नामित volume बना सकते हैं:
यह आपके होस्ट पर माउंट पॉइंट और उपयोगी मेटाडेटा दिखाता है। लेकिन आपको शायद ही कभी इस डायरेक्टरी तक सीधे पहुँचने की ज़रूरत पड़ेगी - यह Docker का काम है।
यदि आप volume के साथ काम कर चुके हैं और उसे हटाना चाहते हैं, तो यह कमांड चलाएं:
प्रोडक्शन सेटअप के लिए, Docker ऐसे volume ड्राइवर्स सपोर्ट करता है जो NFS, AWS EFS या क्लाउड ब्लॉक स्टोरेज जैसे बाहरी स्टोरेज सिस्टम से कनेक्ट होते हैं। आप volume बनाते समय ड्राइवर निर्दिष्ट करते हैं, और बाकी Docker संभालता है। इससे आप डेटा पूरी तरह अपनी होस्ट मशीन के बाहर स्टोर कर सकते हैं, जो high-availability सेटअप्स में ज़रूरी होता है जहाँ कंटेनर सर्वरों के बीच स्थानांतरित होते हैं।
अब आगे, bind mounts पर चर्चा करते हैं।
लोकल डेवलपमेंट के लिए Bind Mounts
Bind mounts आपको कंटेनर के अंदर से सीधे आपके होस्ट फ़ाइलसिस्टम तक पहुँच देते हैं, और यही कारण है कि डेवलपर्स उन्हें पसंद करते हैं।
ये लोकल डेवलपमेंट के लिए परफेक्ट हैं लेकिन ऐसे trade-offs के साथ आते हैं जो उन्हें प्रोडक्शन के लिए जोखिमभरा बना देते हैं। आपको रीयल-टाइम फ़ाइल सिंक और ज़ीरो बिल्ड स्टेप्स मिलते हैं, लेकिन आप पोर्टेबिलिटी खो देते हैं और सुरक्षा में छेद खुल सकते हैं।
Bind mounts कैसे काम करते हैं
एक bind mount आपकी होस्ट मशीन की किसी विशिष्ट डायरेक्टरी को सीधे कंटेनर में मैप करता है।
आप सटीक पाथ निर्दिष्ट करते हैं - जैसे /home/user/myapp - और Docker उसे कंटेनर के अंदर एक पाथ पर उपलब्ध करा देता है। इसमें कोई कॉपीिंग नहीं, कोई Docker-प्रबंधित स्टोरेज नहीं, कोई एब्स्ट्रैक्शन लेयर नहीं। कंटेनर आपकी वास्तविक होस्ट फ़ाइलें देखता है।
यदि आप होस्ट पर कोई फ़ाइल बदलते हैं, तो कंटेनर तुरंत बदलाव देखता है। उसी तरह, यदि आप कंटेनर के अंदर कोई फ़ाइल संशोधित करते हैं, तो वह आपके होस्ट पर अपडेट हो जाती है। दोनों तरफ़ एक ही फ़ाइलों पर रीयल-टाइम में काम हो रहा होता है।
यहाँ bind mount का एक उदाहरण है:
docker run -d\--name dev-app \--mounttype=bind,source=/Users/dradecic/Desktop/app,target=/app \
python:3.14संचालित द्वारा
यह मेरे होस्ट से /Users/dradecic/Desktop/app को कंटेनर के अंदर /app पर माउंट करता है। जब मैं /Users/dradecic/Desktop/app में किसी Python फ़ाइल को अपने टेक्स्ट एडिटर से एडिट करता हूँ, तो कंटेनराइज़्ड ऐप तुरंत बदलाव देख लेता है।
आप छोटा सिंटैक्स भी उपयोग कर सकते हैं:
आम डेवलपमेंट वर्कफ़्लो
सबसे आम उपयोग-केस डेवलपमेंट के दौरान सोर्स कोड को माउंट करना है।
मान लीजिए आप FastAPI एप्लिकेशन बना रहे हैं। आप अपने प्रोजेक्ट डायरेक्टरी को कंटेनर में माउंट कर सकते हैं, hot reload सक्षम कर सकते हैं, और आपके पास पूर्ण डेवलपमेंट वातावरण तैयार है:
Docker कमांड चलाने के बाद, ऐप मेरी होस्ट मशीन से पोर्ट 8000 पर उपलब्ध है:
यदि आप अपने एडिटर में main.py एडिट करके फ़ाइल सेव करते हैं, तो FastAPI स्वतः रीलोड हो जाएगा। कोई इमेज दोबारा बनानी नहीं, कोई कंटेनर रीस्टार्ट नहीं। आप स्थानीय की तरह कोड लिखते हैं, लेकिन आपका ऐप एक सुसंगत कंटेनर वातावरण में चलता है।
जोखिम और सीमाएँ
Bind mounts आपके होस्ट फ़ाइलसिस्टम को कंटेनरों के सामने उजागर करते हैं, और इससे सुरक्षा समस्याएँ पैदा हो सकती हैं।
Bind mount वाला कंटेनर आपके होस्ट पर फ़ाइलें पढ़ और लिख सकता है। कंटेनर को root के रूप में चलाएँ - जो डिफ़ॉल्ट है - तो उसे उन माउंटेड फ़ाइलों पर root एक्सेस मिल जाता है। दुर्भावनापूर्ण कोड या समझौता किया गया कंटेनर माउंटेड डायरेक्टरी में कुछ भी संशोधित या हटा सकता है।
पोर्टेबिलिटी भी एक मुद्दा है।
Bind mounts होस्ट पर विशिष्ट पाथ्स के मौजूद होने पर निर्भर होते हैं। /Users/dradecic/Desktop/app आपके सिस्टम या किसी प्रोडक्शन सर्वर पर मौजूद नहीं है। यह कंटेनरों के "हर जगह काम करता है" वादे को तोड़ देता है।
प्लेटफ़ॉर्म भिन्नताएँ भी मायने रखती हैं। Windows और Mac, Docker चलाने के लिए VM का उपयोग करते हैं, इसलिए bind mounts एक अतिरिक्त ट्रांसलेशन लेयर से गुजरते हैं। इससे फ़ाइल ऑपरेशंस धीमे हो जाते हैं और फ़ाइल वॉचिंग व symlinks के साथ सूक्ष्म बग आ सकते हैं।
प्रोडक्शन वातावरण में bind mounts का कभी उपयोग नहीं करना चाहिए।
ये होस्ट-विशिष्ट पाथ्स पर बहुत अधिक निर्भर हैं, सुरक्षा के नज़रिए से जोखिमपूर्ण हैं, और version control में लाना असंभव है। Volumes इन सभी समस्याओं को हल करते हैं, और इसी वजह से वे प्रोडक्शन मानक हैं।
Bind mounts को डेवलपमेंट टूल की तरह मानें - तेज़, सुविधाजनक, और शक्तिशाली, लेकिन प्रोडक्शन के आस-पास भी नहीं।
अस्थायी डेटा के लिए tmpfs माउंट्स
tmpfs माउंट्स डेटा को आपकी होस्ट की RAM में स्टोर करते हैं, डिस्क पर नहीं। इससे वे ऐसे डेटा के लिए परफेक्ट हैं जिन्हें आप स्थायी नहीं रखना चाहते।
इन-मेमोरी स्टोरेज का व्यवहार
एक tmpfs माउंट पूरी तरह मेमोरी में मौजूद रहता है।
Docker आपकी होस्ट मशीन पर RAM आवंटित करता है और उसे कंटेनर के अंदर फ़ाइलसिस्टम के रूप में उपलब्ध कराता है। tmpfs माउंट पर लिखी फ़ाइल कभी डिस्क को नहीं छूती। डेटा, कंटेनर के रुकने तक मेमोरी में रहता है।
जब आप कंटेनर रोकते हैं, तो tmpfs माउंट में मौजूद सब कुछ हट जाता है। कोई क्लीनअप आवश्यक नहीं, कोई बचे हुए फ़ाइल नहीं, वहाँ क्या था इसका कोई निशान नहीं। हर बार कंटेनर रीस्टार्ट करने पर आपको नया, खाली tmpfs माउंट मिलता है।
संक्षेप में, tmpfs माउंट्स उस डेटा के लिए हैं जिसे आप जान-बूझकर नहीं रखना चाहते - अस्थायी गणनाएँ, सेशन टोकन, या ऐसा संवेदनशील डेटा जो उपयोग के बाद नहीं बचना चाहिए।
आम उपयोग-केस
सबसे आम उपयोग-केस secrets या संवेदनशील डेटा स्टोर करना है।
मान लीजिए आप ऐसा कंटेनर चला रहे हैं जिसे API key या डेटाबेस पासवर्ड चाहिए। इसे tmpfs माउंट में स्टोर करें, और secret कभी डिस्क पर स्टोर नहीं होगा। कंटेनर रुकते ही secret मेमोरी से गायब हो जाता है। कोई ऐसी फ़ाइल नहीं जिसे गलती से version control में commit कर दें या फ़ाइलसिस्टम पर खुली रह जाए।
कैश भी इसके लिए उपयुक्त हैं। build artifacts, compiled कोड, या डाउनलोड की गई dependencies जिन्हें आप वैसे भी दोबारा बनाएँगे, उन्हें persist होने की ज़रूरत नहीं। tmpfs में रखें ताकि कंटेनर के lifetime के दौरान तेज़ एक्सेस मिले, और काम ख़त्म होने पर उन्हें गायब होने दें।
अस्थायी फ़ाइलें भी यहाँ अच्छी तरह फिट बैठती हैं - जैसे सेशन डेटा, लॉक फ़ाइलें, या इंटरमीडिएट प्रोसेसिंग परिणाम जो केवल कंटेनर चलते समय मायने रखते हैं।
बेसिक कॉन्फ़िगरेशन
--tmpfs फ़्लैग का उपयोग करके tmpfs माउंट बनाने के लिए यह कमांड चलाएँ:
docker run -d\--name temp-app \--tmpfs /tmp:rw,size=100m \
python:3.14संचालित द्वारा
यह कंटेनर के अंदर /tmp पर 100MB का tmpfs माउंट बनाता है। size विकल्प यह सीमित करता है कि माउंट कितनी RAM उपयोग कर सकता है।
आप --mount सिंटैक्स भी उपयोग कर सकते हैं:
docker run -d\--name temp-app \--mounttype=tmpfs,destination=/tmp,tmpfs-size=104857600\
python:3.14संचालित द्वारा
tmpfs-size का मान bytes में होता है - 104857600 bytes यानी 100MB।
यदि आप size लिमिट निर्दिष्ट नहीं करते, तो tmpfs आपके सिस्टम की आधी RAM तक उपयोग कर सकता है। यह खतरनाक है - कारण स्पष्ट हैं। हमेशा स्पष्ट size लिमिट सेट करें।
एक बड़ी कमी यह है कि tmpfs माउंट्स केवल Linux पर काम करते हैं।
Mac और Windows Docker Desktop इन्हें सपोर्ट नहीं करते क्योंकि वे Docker को Linux VM के अंदर चलाते हैं, और tmpfs को सीधे kernel सपोर्ट चाहिए।
Docker माउंट सिंटैक्स और कॉन्फ़िगरेशन
Docker आपको माउंट्स परिभाषित करने के दो तरीके देता है, और सही सिंटैक्स चुनने से आपकी कमांड्स पढ़ने और डिबग करने में आसान हो जाती हैं।
दोनों तरीके काम करते हैं, लेकिन जब आपको एडवांस्ड विकल्पों या एक ही कंटेनर में कई माउंट्स की ज़रूरत हो, तो एक तरीका बेहतर स्केल करता है।
-mount बनाम --volume
--mount फ़्लैग explicit key-value पेयर्स उपयोग करता है, जबकि -v या --volume colon-सेपरेटेड स्ट्रिंग का उपयोग करता है।
यहाँ एक ही volume माउंट दोनों सिंटैक्स में दिया है:
# Using --mountdocker run -d\--mounttype=volume,source=mydata,target=/app/data \
python:3.14
# Using -vdocker run -d\-v mydata:/app/data \
python:3.14संचालित द्वारा
दोनों mydata नामक एक volume बनाते हैं और उसे कंटेनर में /app/data पर माउंट करते हैं।
बेसिक सेटअप से आगे की किसी भी चीज़ के लिए --mount का उपयोग करें। यह अधिक verbose है, लेकिन explicit keys यह स्पष्ट करती हैं कि हर भाग क्या करता है। जब आप read-only एक्सेस या कस्टम volume ड्राइवर्स जैसे विकल्प जोड़ते हैं, तो यह पढ़ने योग्य बना रहता है जबकि -v एक गूढ़ स्ट्रिंग जैसा लग सकता है।
-v सिंटैक्स हाथ से टाइप की गई सरल डेवलपमेंट वर्कफ़्लो कमांड्स के लिए ठीक है।
सामान्य माउंट विकल्प
readonly विकल्प कंटेनरों को माउंटेड डेटा में संशोधन करने से रोकता है:
docker run -d\--mounttype=volume,source=mydata,target=/app/data,readonly \
python:3.14संचालित द्वारा
यह कॉन्फ़िगरेशन फ़ाइलों या reference डेटा के लिए उपयोगी है जिन्हें कंटेनर पढ़ें लेकिन कभी बदलें नहीं। readonly माउंट पर लिखने की कोशिश करने वाला कंटेनर permission error पाता है।
Volumes के लिए, volume-nocopy विकल्प कंटेनर इमेज से मौजूदा डेटा को volume में कॉपी करने को स्किप करता है:
docker run -d\--mounttype=volume,source=mydata,target=/app/data,volume-nocopy \
python:3.14संचालित द्वारा
डिफ़ॉल्ट रूप से, Docker इमेज में माउंट पॉइंट पर जो भी मौजूद होता है, उसे नए volume में कॉपी कर देता है। जब आप volume-nocopy सेट करते हैं, तो इमेज में क्या है इससे फर्क नहीं पड़ता, आपको खाली volume मिलता है।
tmpfs माउंट्स के लिए, tmpfs-size विकल्प मेमोरी लिमिट सेट करता है:
docker run -d\--mounttype=tmpfs,target=/tmp,tmpfs-size=104857600\
python:3.14संचालित द्वारा
यह tmpfs माउंट को 100MB पर कैप करता है। इसके बिना, tmpfs माउंट उपलब्ध सारी RAM खपा सकता है।
मौजूदा डेटा के ऊपर माउंट करना
जब आप कंटेनर इमेज में पहले से मौजूद किसी डायरेक्टरी पर माउंट करते हैं, तो माउंट वहाँ मौजूद हर चीज़ को पूरी तरह छिपा देता है।
मान लीजिए आपकी इमेज में /app/data डायरेक्टरी है जिसमें बिल्ट-इन कॉन्फ़िग फ़ाइलें हैं। जब आप /app/data पर volume माउंट करते हैं, तो वे कॉन्फ़िग फ़ाइलें गायब हो जाएँगी। कंटेनर केवल volume में मौजूद चीज़ें ही देखेगा।
यह सभी माउंट प्रकारों पर लागू होता है - volumes, bind mounts, और tmpfs। माउंटेड कंटेंट को प्राथमिकता मिलती है, और मूल डायरेक्टरी माउंट सक्रिय रहने तक अप्राप्य हो जाती है।
Docker Compose के साथ माउंट्स का उपयोग
Docker Compose आपके एप्लिकेशन स्टैक में कई कंटेनरों के बीच माउंट्स को परिभाषित और साझा करना आसान बनाता है।
लंबी docker run कमांड्स के साथ माउंट फ़्लैग्स टाइप करने के बजाय, आप सब कुछ docker-compose.yml फ़ाइल में घोषित करते हैं। मैं आपको दिखाता हूँ कैसे।
Compose में volumes और bind mounts परिभाषित करना
यहाँ एक Compose फ़ाइल है जिसमें volume और bind mount दोनों के उदाहरण हैं:
services:
service-1:
image: ubuntu:latest
command: sleep infinity
volumes:
- ./code:/app # Bind mount for development
- shared:/data # Named volume shared with worker
service-2:
image: ubuntu:latest
command: sleep infinity
volumes:
- shared:/data # Same volume as service-1
volumes:
shared:संचालित द्वारा
volumes की-के अंतर्गत हर सर्विस के लिए क्या माउंट होगा, यह परिभाषित होता है। ./code जैसे relative पाथ bind mounts बनाते हैं, जबकि shared जैसे नाम नामित volumes को संदर्भित करते हैं।
टॉप-लेवल volumes सेक्शन उन नामित volumes की घोषणा करता है जिन्हें Compose बनाता और प्रबंधित करता है। service-1 और service-2 दोनों एक ही shared volume माउंट करते हैं, इसलिए वे एक जैसी फ़ाइलें देखते हैं। एक कंटेनर से फ़ाइल लिखें, और दूसरा कंटेनर उसे तुरंत पढ़ सकता है।
sleep infinity कमांड कंटेनरों को चलता रखता है ताकि आप उनमें exec कर सकें - सिर्फ़ डेमो उद्देश्यों के लिए।
डेटा को स्थायी रखना और सत्यापित करना
docker compose up -d से अपना स्टैक शुरू करें, फिर जाँचें कि माउंट्स काम कर रहे हैं या नहीं:
# Write data to the shared volume from appdocker compose exec service-1 sh-c"echo 'test' > /data/file.txt"# Read it from workerdocker compose exec service-2 cat /data/file.txtसंचालित द्वारा
यदि दोनों कमांड काम करती हैं, तो आपके volumes सही तरह से कॉन्फ़िगर हैं।
आपके नामित volumes फिर भी मौजूद रहेंगे। यदि आप स्टैक को फिर docker compose up -d से शुरू करते हैं, तो पहले लिखा हुआ डेटा अब भी मौजूद रहेगा। इसी तरह डेटाबेस डिप्लॉयमेंट्स के पार बने रहते हैं - volume कंटेनर से अधिक समय तक जीवित रहता है।
स्टैक को रोकते समय volumes हटाने के लिए -v फ़्लैग जोड़ें:
init कंटेनर seed डेटा बनाता है और उसे shared volume में कॉपी करता है, फिर बाहर निकलता है। service-1 और service-2 बाद में शुरू होते हैं और तैयार seeded डेटा पाते हैं।
Compose, कई कंटेनरों और उनके shared स्टोरेज का समन्वय एक ही, version-controlled फ़ाइल में संभालता है।
Docker माउंट का प्रदर्शन और सुरक्षा
गलत माउंट प्रकार चुनने से आपके कंटेनर धीमे हो सकते हैं या ऐसे सुरक्षा छेद बन सकते हैं जिनका आपको पता भी न हो। यदि आप ऐसा नहीं चाहते, तो यह सेक्शन पढ़ें।
माउंट प्रकारों के बीच प्रदर्शन trade-offs
Linux पर volumes सबसे अच्छा प्रदर्शन देते हैं क्योंकि वे सीधे होस्ट फ़ाइलसिस्टम पर बिना किसी ट्रांसलेशन लेयर के स्टोर होते हैं।
Mac और Windows पर Docker एक Linux VM के अंदर चलता है। Volumes फिर भी अच्छा प्रदर्शन देते हैं क्योंकि वे उसी VM के भीतर रहते हैं। दूसरी ओर, bind mounts को आपके होस्ट OS और Linux VM के बीच फ़ाइलों को सिंक करना पड़ता है, जिससे overhead बढ़ता है। Mac और Windows पर bind mounts पर फ़ाइल ऑपरेशंस, native Linux की तुलना में काफी धीमे हो सकते हैं।
tmpfs पढ़ने और लिखने के लिए सबसे तेज़ विकल्प है क्योंकि सब कुछ RAM में होता है। कोई डिस्क I/O नहीं, कोई फ़ाइलसिस्टम overhead नहीं। लेकिन आप उपलब्ध मेमोरी से सीमित होते हैं, और कंटेनर रुकते ही डेटा गायब हो जाता है।
यदि आप Linux पर हैं और अधिकतम प्रदर्शन चाहिए, तो volumes का उपयोग करें। यदि आप Mac या Windows पर हैं और डेवलपमेंट के दौरान फ़ाइल ऑपरेशंस धीमे लगते हैं, तो संभवतः आप bind mount overhead का सामना कर रहे हैं। प्रोडक्शन वर्कलोड्स के लिए volumes पर स्विच करें।
माउंट्स के सुरक्षा निहितार्थ
हर माउंट कंटेनरों को उनके आइसोलेटेड फ़ाइलसिस्टम के बाहर किसी चीज़ तक पहुँच देता है, और इससे जोखिम पैदा होता है।
Bind mounts सबसे बड़ा चिंताजनक पहलू हैं। यदि आप /home/user को कंटेनर में माउंट करते हैं, तो समझौता किया गया कंटेनर आपके SSH keys पढ़ सकता है, आपकी shell कॉन्फ़िग में बदलाव कर सकता है, या आपके पूरे home डायरेक्टरी में फ़ाइलें हटा सकता है। उसी कंटेनर को root के रूप में चलाएँ - जो डिफ़ॉल्ट है - तो उसे उन फ़ाइलों पर root-स्तरीय एक्सेस मिलता है।
Volumes इस जोखिम को कम करते हैं क्योंकि वे Docker की स्टोरेज डायरेक्टरी में अलग-थलग रहते हैं। कंटेनर volumes के माध्यम से मनमाने होस्ट पाथ्स माउंट नहीं कर सकता। लेकिन यदि आप volumes को लापरवाही से साझा करते हैं, तो उनके जरिए कंटेनरों के बीच डेटा लीक हो सकता है।
tmpfs माउंट्स persistence जोखिम को न्यूनतम करते हैं - मेमोरी में स्टोर किए गए secrets कंटेनर रुकने पर गायब हो जाते हैं। लेकिन वे runtime हमलों से नहीं बचाते जहाँ समझौता किया गया कंटेनर मेमोरी से secrets पढ़ लेता है।
सामान्य नियम यह है कि माउंट्स कंटेनर आइसोलेशन को तोड़ते हैं, इसलिए उनका सावधानी से उपयोग करें।
सुरक्षित माउंट्स के लिए सर्वोत्तम प्रथाएँ
सिर्फ़ वही माउंट करें जिसकी कंटेनरों को आवश्यकता है, और उससे अधिक नहीं।
पूरी प्रोजेक्ट डायरेक्टरी माउंट करने के बजाय, केवल वही सबडायरेक्टरी माउंट करें जिसका कंटेनर उपयोग करता है। /var/log को write एक्सेस के साथ माउंट करने के बजाय, यदि कंटेनर केवल लॉग पढ़ता है तो उसे read-only माउंट करें।
जहाँ भी संभव हो, readonly विकल्प का उपयोग करें:
docker run -d\--mounttype=bind,source=/app/config,target=/config,readonly \
ubuntu:latestसंचालित द्वारा
यह कंटेनरों को माउंटेड डेटा में संशोधन करने से रोकता है, जिससे समझौता होने की स्थिति में नुकसान सीमित रहता है।
Bind mount कमजोरियों के प्रभाव को कम करने के लिए कंटेनरों को non-root उपयोगकर्ताओं के रूप में चलाएँ। अपने Dockerfile में एक उपयोगकर्ता बनाएँ और कंटेनर शुरू होने से पहले उस पर स्विच करें:
अप्रयुक्त volumes को नियमित रूप से docker volume prune के साथ साफ़ करें। पुराने volumes समय के साथ इकट्ठा हो जाते हैं, डिस्क स्पेस लेते हैं और हटाए गए कंटेनरों से संवेदनशील डेटा भी रख सकते हैं।
कभी भी /, /etc या /var जैसे संवेदनशील होस्ट डायरेक्टरीज़ को माउंट न करें, जब तक कि आपके पास कोई विशिष्ट कारण न हो और आप जोखिम समझते न हों। हर माउंट का एक स्पष्ट उद्देश्य और न्यूनतम दायरा होना चाहिए।
Docker माउंट मुद्दों का ट्रबलशूटिंग
माउंट से जुड़ी समस्याएँ आमतौर पर परमिशन एरर्स, गायब फ़ाइलें, या कंटेनरों के शुरू न होने के रूप में दिखती हैं - और लगभग हमेशा वही कारण होते हैं।
यहाँ सबसे आम समस्याओं का निदान और समाधान कैसे करें:
परमिशन और ओनरशिप एरर्स
परमिशन एरर्स तब होती हैं जब कंटेनर के अंदर का उपयोगकर्ता माउंटेड फ़ाइलों तक पहुँच नहीं रखता।
Docker कंटेनर डिफ़ॉल्ट रूप से root के रूप में चलते हैं। जब root किसी bind mount में फ़ाइल बनाता है, तो वह फ़ाइल आपके होस्ट पर root की ओनरशिप रखती है। यदि आप उसे अपने सामान्य यूज़र अकाउंट से एडिट करने की कोशिश करेंगे, तो आपको permission denied एरर मिलेगा।
उल्टा भी होता है। जिस डायरेक्टरी के आप ओनर हैं उसे ऐसे कंटेनर में माउंट करें जो non-root यूज़र के रूप में चलता है, और हो सकता है कंटेनर उसमें लिख न सके।
माउंटेड डायरेक्टरी पर ls -la चलाकर फ़ाइल ओनरशिप जाँच सकते हैं:
यदि फ़ाइलें root की ओनरशिप में हैं लेकिन आपका कंटेनर किसी अन्य यूज़र के रूप में चलता है, तो mismatch है। इसे कंटेनर को उन्हीं यूज़र/ग्रुप IDs के साथ चलाकर ठीक करें जो फ़ाइलों की ओनरशिप से मेल खाते हैं:
docker run -d\--user$(id-u):$(id-g)\-v ./data:/app/data \
ubuntu:latestसंचालित द्वारा
यह कंटेनर को root के बजाय आपके वर्तमान यूज़र के रूप में चलाता है, जिससे bind mount में फ़ाइलों की ओनरशिप मैच होती है।
Volumes के लिए, जब कंटेनर फ़ाइलें बनाते हैं तो Docker परमिशन अपने आप संभालता है। लेकिन यदि एरर्स आ रही हैं, तो देखें कि कंटेनराइज़्ड ऐप किस यूज़र के रूप में चलता है और क्या उसे माउंट पॉइंट पर write एक्सेस है।
पाथ और कॉन्फ़िगरेशन की गलतियाँ
सबसे आम गलती होस्ट पर मौजूद न होने वाले पाथ को माउंट करना है।
यदि आप /home/user/project माउंट करने की कोशिश करते हैं जबकि वह डायरेक्टरी मौजूद नहीं है, तो Docker root ओनरशिप वाली एक खाली डायरेक्टरी बना देगा। आपका कंटेनर शुरू हो जाएगा, लेकिन वह गलत चीज़ माउंट कर रहा होगा - आपकी वास्तविक प्रोजेक्ट के बजाय एक खाली डायरेक्टरी।
हमेशा माउंट करने से पहले पाथ्स के अस्तित्व की पुष्टि करें:
यदि डायरेक्टरी मौजूद नहीं है, तो पहले उसे बनाएँ या अपनी माउंट कमांड में पाथ ठीक करें।
Docker Compose में, relative पाथ्स आपके docker-compose.yml फ़ाइल वाली डायरेक्टरी से रिज़ॉल्व होते हैं। यदि आपकी फ़ाइल /home/user/app/ में है और आप ./data उपयोग करते हैं, तो Docker /home/user/app/data ढूँढता है।
Compose फ़ाइल को कहीं और ले जाएँ, और माउंट टूट सकता है।
एक और आम गलती कंटेनर के अंदर गलत target पाथ पर माउंट करना है। यदि आपका ऐप /data अपेक्षा करता है और आप /app/data पर माउंट करते हैं, तो ऐप अपनी फ़ाइलें नहीं ढूँढ पाएगा। अपने एप्लिकेशन के दस्तावेज़ या Dockerfile देखें कि उसे डेटा कहाँ चाहिए।
प्लेटफ़ॉर्म-विशिष्ट विशेषताएँ
Linux पर bind mounts सीधे होस्ट फ़ाइलसिस्टम के साथ काम करते हैं।
Mac और Windows पर Docker एक Linux VM के अंदर चलता है। Bind mounts आपके होस्ट OS और उस VM के बीच फ़ाइलों को सिंक करते हैं, जिससे टाइमिंग इश्यूज आते हैं। फ़ाइल वॉचर्स - जो फ़ाइल बदलने पर आपके ऐप को रीलोड करते हैं - कभी-कभी सिंक देरी के कारण अपडेट मिस कर देते हैं।
Mac और Windows फ़ाइल परमिशन को अलग तरीके से संभालते हैं। VM होस्ट OS और Linux के बीच परमिशन का अनुवाद करता है, जिससे कंटेनरों के अंदर फ़ाइलें गलत ओनरशिप के साथ दिख सकती हैं।
Symlinks, Mac और Windows पर bind mounts में भरोसेमंद रूप से काम नहीं करते। VM हमेशा उन symlinks को resolve नहीं कर पाता जो माउंटेड डायरेक्टरी के बाहर की ओर इशारा करते हैं, इसलिए कंटेनरों के अंदर फ़ाइलें गायब या टूटी हुई दिख सकती हैं।
tmpfs माउंट्स Mac और Windows पर बिल्कुल काम नहीं करते क्योंकि VM, tmpfs को होस्ट तक एक्सपोज़ नहीं करता। यदि आप tmpfs माउंट का उपयोग करने की कोशिश करते हैं, तो Docker चुपचाप उसे नज़रअंदाज कर देगा या वर्ज़न पर निर्भर करते हुए एरर देगा।
यदि आप Mac या Windows पर डेवलपमेंट कर रहे हैं और अजीब फ़ाइल सिंक समस्याएँ आ रही हैं, तो बेहतर प्रदर्शन और विश्वसनीयता के लिए नामित volumes पर स्विच करें। Bind mounts को उन डेवलपमेंट वर्कफ़्लोज़ के लिए बचाकर रखें जहाँ रीयल-टाइम सिंक परफेक्ट सुसंगतता से अधिक मायने रखता है।
निष्कर्ष
समाप्त करते हुए, ऐसे प्रोडक्शन डेटा के लिए volumes का उपयोग करें जिसे बनाए रखना ज़रूरी है, जैसे डेटाबेस, अपलोड की गई फ़ाइलें, एप्लिकेशन स्टेट - यानी कुछ भी जिसे आप खो नहीं सकते। ये Docker-प्रबंधित हैं, प्लेटफ़ॉर्म्स के पार पोर्टेबल हैं, और महत्वपूर्ण डेटा के लिए सबसे सुरक्षित विकल्प हैं।
Bind mounts, डेवलपमेंट वर्कफ़्लोज़ के लिए उपयुक्त हैं जहाँ आपको होस्ट और कंटेनरों के बीच रीयल-टाइम फ़ाइल सिंक चाहिए। आप एडिटर में कोड एडिट करें, और कंटेनराइज़्ड ऐप में बदलाव तुरंत दिखें। लेकिन इन्हें प्रोडक्शन से दूर रखें क्योंकि ये होस्ट-विशिष्ट पाथ्स पर बहुत निर्भर हैं और अनावश्यक सुरक्षा जोखिम पैदा करते हैं।
क्रोएशिया में स्थित सीनियर डेटा साइंटिस्ट। 700 से अधिक प्रकाशित लेखों के साथ टॉप टेक राइटर, जिनसे 10M+ व्यूज़ प्राप्त हुए। Machine Learning Automation with TPOT के पुस्तक लेखक।
Docker माउंट FAQs
मैं Docker volume प्रदर्शन कैसे अनुकूलित करूँ?⌄
Mac और Windows पर bind mounts की बजाय volumes का उपयोग करें - वे Docker के Linux VM के अंदर स्टोर होते हैं और आपके होस्ट OS और VM के बीच सिंक ओवरहेड से बचते हैं। सभी प्लेटफ़ॉर्म्स पर, जब तक आवश्यक न हो, heavy write ऑपरेशंस वाले पाथ्स पर volumes माउंट करने से बचें। Read-heavy वर्कलोड्स के लिए, फ़ाइलसिस्टम ओवरहेड कम करने हेतु readonly माउंट विकल्प पर विचार करें।
प्रोडक्शन में Docker volumes उपयोग करने की सर्वोत्तम प्रथाएँ क्या हैं?⌄
हमेशा anonymous के बजाय named volumes का उपयोग करें ताकि आप उन्हें आसानी से ट्रैक और मैनेज कर सकें। वॉल्यूम डेटा को बाहरी स्टोरेज पर कॉपी करके या क्लाउड स्टोरेज सेवाओं से जुड़ने वाले volume ड्राइवर्स का उपयोग करके नियमित बैकअप सेट करें। डिस्क स्पेस समस्याओं से बचने के लिए docker volume prune से अप्रयुक्त volumes साफ़ करें, और कभी भी प्रोडक्शन व डेवलपमेंट वातावरणों के बीच volumes साझा न करें।
Docker volumes और bind mounts में क्या अंतर है?⌄
Volumes Docker द्वारा प्रबंधित होते हैं और Docker-नियंत्रित समर्पित डायरेक्टरी में स्टोर रहते हैं, जिससे वे पोर्टेबल और प्लेटफ़ॉर्म-इंडिपेंडेंट बनते हैं। Bind mounts विशिष्ट होस्ट पाथ्स को सीधे कंटेनरों में मैप करते हैं, जिससे रीयल-टाइम फ़ाइल सिंक मिलता है लेकिन आपकी सेटअप सटीक डायरेक्टरी संरचनाओं से बंध जाता है। Volumes Linux, Mac, और Windows पर सुसंगत रूप से काम करते हैं, जबकि Mac और Windows पर bind mounts, VM ओवरहेड के कारण धीमे चलते हैं।
Docker कंटेनरों का उपयोग करते समय मैं डेटा persistence कैसे सुनिश्चित करूँ?⌄
Volumes को उन डायरेक्टरीज़ पर माउंट करें जहाँ आपका एप्लिकेशन डेटा स्टोर करता है - जैसे डेटाबेस के लिए /var/lib/postgresql/data या यूज़र फ़ाइलों के लिए /app/uploads। जिस चीज़ को आपको बचाकर रखना है उसके लिए कभी भी कंटेनर की writable लेयर पर निर्भर न रहें, क्योंकि कंटेनर हटाने पर वह डेटा गायब हो जाता है। Docker Compose में, शीर्ष-स्तरीय volumes सेक्शन में volumes घोषित करें और अपनी सर्विसेज़ में उन्हें संदर्भित करें ताकि डेटा कंटेनर रीस्टार्ट्स और रिमूवल्स के बाद भी बना रहे।
How do I ensure data persistence when using Docker containers?⌄
Mount volumes to directories where your application stores data - like /var/lib/postgresql/data for databases or /app/uploads for user files. Never rely on the container's writable layer for anything you need to keep, because that data disappears when you remove the container. In Docker Compose, declare volumes in the top-level volumes section and reference them in your services to ensure data survives container restarts and removals.
मान लीजिए आपने किसी कॉन्फ़िगरेशन फ़ाइल को अपडेट करने के लिए Docker कंटेनर रोका, लेकिन दोबारा शुरू करने पर सारा डेटा गायब था। मेरे साथ भी ऐसा हुआ है।
ऐसा इसलिए होता है क्योंकि कंटेनर डिफ़ॉल्ट रूप से ephemeral होते हैं – जब उन्हें हटाया जाता है, तो उनकी writable लेयर में संग्रहीत कोई भी डेटा गायब हो जाता है। वास्तविक एप्लिकेशन ऐसे नहीं चल सकते। आपको ऐसे डेटाबेस चाहिए जो बने रहें, ऐसे कॉन्फ़िग फ़ाइलें जो रीस्टार्ट के बाद भी बचीं रहें, और ऐसे लॉग जिन्हें आप वास्तव में एक्सेस कर सकें।
Docker माउंट इस समस्या को कंटेनर स्टोरेज को बाहरी लोकेशनों से जोड़कर हल करता है। इसके तीन प्रकार हैं: प्रोडक्शन डेटा के लिए volumes, डेवलपमेंट वर्कफ़्लो के लिए bind mounts, और tmpfs जो मेमोरी में अस्थायी फ़ाइलें रखता है।
इस लेख में, मैं आपको आपके उपयोग-केस के लिए सही माउंट प्रकार चुनने और उसे सही तरीके से लागू करने की प्रक्रिया समझाऊंगा। यहाँ कवर की गई हर बात समझने के लिए, आपको Docker और कंटेनराइज़ेशन की अच्छी समझ चाहिए। जल्दी गति पकड़ने के लिए हमारा Intermediate Docker कोर्स करें।
Docker स्टोरेज को कैसे संभालता है
Docker कंटेनर layered फ़ाइलसिस्टम का उपयोग करते हैं जो डिफ़ॉल्ट रूप से हर चीज़ को अस्थायी मानता है।
जब आप Docker इमेज बनाते हैं, तो आपके Dockerfile की हर इंस्ट्रक्शन एक नई read-only लेयर बनाती है। ये लेयरें एक-दूसरे के ऊपर कार्डों की गड्डी की तरह स्टैक होती हैं। यदि आप Python इंस्टॉल किए हुए Ubuntu इमेज को pull करते हैं, तो आपको बेस OS के लिए एक लेयर और Python के लिए दूसरी लेयर मिलेगी।
पेंच यह है कि ये सारी लेयरें read-only होती हैं। आप इन्हें संशोधित नहीं कर सकते।
कंटेनर फ़ाइलसिस्टम और writable लेयर
जब आप कंटेनर शुरू करते हैं, Docker सबसे ऊपर एक और लेयर जोड़ता है - writable कंटेनर लेयर।
सारी परिवर्तन यहीं होते हैं। आप जो भी फ़ाइल बनाते हैं, जो भी कॉन्फ़िग बदलते हैं, और जो भी टेबल रिकॉर्ड जोड़ते हैं, वह सब यहीं रहता है।
यह सुनने में अच्छा लगता है, लेकिन समस्या यह है कि यह लेयर कंटेनर के lifecycle से बंधी होती है।
जब आप
docker rmसे कंटेनर को रोककर हटा देते हैं, तो writable लेयर चली जाती है। आपने जो कुछ भी किया था, वह सब खत्म। Docker पुष्टि नहीं मांगता। यह बस सब कुछ हटा देता है।यह डिज़ाइन stateless ऐप्स के लिए ठीक है जिन्हें रन के बीच कुछ याद नहीं रखना होता। लेकिन वास्तविक एप्लिकेशन stateless नहीं होते।
माउंट्स क्यों आवश्यक हैं
प्रोडक्शन वातावरण में writable लेयर के दो बड़े मुद्दे हैं।
पहला, कंटेनर रुकने पर आपका डेटा खो जाता है। किसी ऐसे डेटाबेस कंटेनर का क्या फ़ायदा जो रीस्टार्ट के बाद सभी rows भूल जाए? मेरे ख्याल से इसका उपयोग सिर्फ़ आपके ऐप के इंटीग्रेशन टेस्ट चलाने में ही हो सकता है।
दूसरा, आप कंटेनरों के बीच डेटा साझा नहीं कर सकते। मान लीजिए आप एक वेब ऐप और एक बैकग्राउंड वर्कर चला रहे हैं जिन्हें एक ही फ़ाइलों की जरूरत है। अगर वे फ़ाइलें किसी एक कंटेनर की writable लेयर में हैं, तो दूसरा कंटेनर उन्हें नहीं देख पाएगा।
Docker माउंट्स दोनों समस्याओं को हल करते हैं क्योंकि वे कंटेनरों को ऐसे स्टोरेज से जोड़ते हैं जो कंटेनर lifecycle से बाहर मौजूद होता है। आप अपने होस्ट मशीन से कोई डायरेक्टरी या Docker-प्रबंधित volume माउंट कर सकते हैं। कंटेनर हटाए जाने पर भी आपका डेटा बना रहता है। एक से अधिक कंटेनर एक ही लोकेशन को माउंट कर सकते हैं और वास्तविक समय में फ़ाइलें साझा कर सकते हैं।
इसीलिए आपको माउंट्स का उपयोग करना चाहिए। आगे हम माउंट प्रकारों पर नज़र डालेंगे, और फिर मैं दिखाऊंगा कि वे कैसे काम करते हैं।
Docker माउंट प्रकार एक नज़र में
Docker आपको persistent डेटा संभालने के तीन तरीके देता है, और प्रत्येक अलग समस्या हल करता है। यहाँ हर प्रकार क्या करता है और कब उपयोग करना चाहिए:
Volumes
Volumes, persistent स्टोरेज के लिए Docker का डिफ़ॉल्ट समाधान हैं।
Docker आपकी होस्ट मशीन पर एक समर्पित डायरेक्टरी में volumes बनाता और प्रबंधित करता है। आपको यह जानने की ज़रूरत नहीं कि वह डायरेक्टरी कहाँ है, सब कुछ Docker संभालता है। इससे volumes अलग-अलग सिस्टमों में पोर्टेबल रहते हैं और प्रोडक्शन में उपयोग के लिए सुरक्षित होते हैं।
जब आप कंटेनर हटाते हैं, तो volume जस का तस रहता है। यदि आप एक नया कंटेनर शुरू करके उसी volume को अटैच करते हैं, तो आपका सारा डेटा वहीं मिलेगा जहाँ आपने छोड़ा था।
Volumes प्रोडक्शन डेटाबेस, एप्लिकेशन स्टेट, और ऐसा कोई भी डेटा जिसके खोने का जोखिम आप नहीं उठा सकते, के लिए सबसे बेहतर हैं।
Bind mounts
Bind mounts आपकी होस्ट मशीन की किसी विशेष डायरेक्टरी को सीधे कंटेनर से जोड़ते हैं।
आप होस्ट पर सटीक पाथ चुनते हैं - जैसे
/home/user/project- और Docker उसे कंटेनर में मैप कर देता है। जब आप होस्ट पर कोई फ़ाइल बदलते हैं, तो कंटेनर तुरंत बदलाव देखता है। कंटेनर में फ़ाइल बदलें, और वह आपके होस्ट पर दिखाई देगी।यह रीयल-टाइम सिंक bind mounts को डेवलपमेंट के लिए बेहतरीन बनाता है।
लेकिन bind mounts के साथ जोखिम आते हैं। ये होस्ट पाथ्स को कंटेनरों के सामने खोलते हैं और ऐसी डायरेक्टरी संरचनाओं पर निर्भर रहते हैं जो अन्य मशीनों पर मौजूद न हों।
tmpfs माउंट्स
tmpfs माउंट्स डेटा को डिस्क के बजाय आपकी होस्ट की मेमोरी में स्टोर करते हैं।
फ़ाइलसिस्टम पर कुछ भी नहीं लिखा जाता। कंटेनर रुकते ही डेटा पूरी तरह गायब हो जाता है। इससे tmpfs माउंट्स अस्थायी डेटा जिसे आप स्थायी रखना नहीं चाहते के लिए उपयोगी बनते हैं - जैसे ऑथेंटिकेशन टोकन, सेशन डेटा, या कैश फ़ाइलें जिन्हें आप वैसे भी दोबारा बनाएंगे।
हालाँकि, tmpfs माउंट्स उपलब्ध RAM से सीमित होते हैं और केवल Linux होस्ट्स पर काम करते हैं।
Persistent डेटा के लिए Docker Volumes
Volumes Docker का प्रोडक्शन-रेडी स्टोरेज समाधान हैं, और आपको डिफ़ॉल्ट रूप से इन्हें ही उपयोग करना चाहिए जब तक कि न करने का कोई खास कारण न हो।
ये पूरी तरह Docker द्वारा प्रबंधित होते हैं, अलग-अलग प्लेटफ़ॉर्म पर समान रूप से काम करते हैं, और डिजाइन के हिसाब से कंटेनर हटाने के बाद भी बने रहते हैं। यदि आप डेटाबेस चला रहे हैं, एप्लिकेशन स्टेट स्टोर कर रहे हैं, या ऐसा कोई भी डेटा संभाल रहे हैं जिसे एक कंटेनर से अधिक समय तक जीवित रहना है, तो volumes ही समाधान हैं।
Docker volumes कैसे काम करते हैं
Docker आपकी होस्ट मशीन पर एक समर्पित डायरेक्टरी में volumes स्टोर करता है:
/var/lib/docker/volumes/~/Library/Containers/com.docker.docker/Data/vms/0/data/\\wsl$\docker-desktop-data\data\docker\volumes\, WSL2 backend मानकरआप इस डायरेक्टरी को सीधे प्रबंधित नहीं करते। Docker अपनी API के ज़रिए निर्माण, परमिशन, और क्लीनअप संभालता है। यह अलगाव सुनिश्चित करता है कि Linux, Mac या Windows पर volumes एक ही तरह से काम करते हैं, जिससे आपका कंटेनर सेटअप डेवलपमेंट और प्रोडक्शन वातावरणों में पोर्टेबल बनता है।
यहाँ याद रखने वाली बात यह है कि volumes किसी भी कंटेनर से स्वतंत्र रूप से मौजूद रहते हैं। जब आप कोई volume बनाते हैं, उसे कंटेनर से जोड़ते हैं, ऐप चलाते हैं, फिर कंटेनर को रोककर हटा देते हैं, तब भी volume अपने स्थान पर और आपके सभी डेटा के साथ बना रहता है।
यदि आप नया कंटेनर शुरू करके वही volume अटैच करते हैं, तो आपका डेटा वहीं मिलेगा।
Volumes बनाना और पुन: उपयोग करना
आप किसी भी कंटेनर को शुरू करने से पहले एक नामित volume बना सकते हैं:
फिर कंटेनर रन करते समय
--mountफ़्लैग का उपयोग करके इसे अटैच करें:यह
mydatavolume को कंटेनर के अंदर/var/lib/postgresql/dataपर माउंट करता है, जहाँ Postgres अपने डेटाबेस फ़ाइलें स्टोर करता है।अब आप इस कंटेनर को रोककर हटा सकते हैं, फिर उसी volume के साथ नया कंटेनर शुरू कर सकते हैं:
आपका डेटाबेस सभी टेबल और रो सहित वापस मिल जाएगा।
यही volumes का मूल उद्देश्य है - कंटेनर lifecycle के पार डेटा को बनाए रखना।
Volume डेटा का प्रबंधन और रखरखाव
आप अपने सिस्टम पर मौजूद volumes देखने के लिए यह कमांड चला सकते हैं:
फिर किसी विशिष्ट volume को inspect करने के लिए यह कमांड चलाएं, ताकि पता चले यह कहाँ स्टोर है और किन कंटेनरों द्वारा उपयोग होता है:
यह आपके होस्ट पर माउंट पॉइंट और उपयोगी मेटाडेटा दिखाता है। लेकिन आपको शायद ही कभी इस डायरेक्टरी तक सीधे पहुँचने की ज़रूरत पड़ेगी - यह Docker का काम है।
यदि आप volume के साथ काम कर चुके हैं और उसे हटाना चाहते हैं, तो यह कमांड चलाएं:
Docker आपको किसी चल रहे कंटेनर से जुड़े volume को हटाने नहीं देगा। पहले कंटेनर को रोकें, फिर volume हटाएँ।
अंत में, यदि आप संसाधन साफ़ करना और कुछ डिस्क स्पेस वापस पाना चाहते हैं, तो यह कमांड चलाकर एक साथ सभी अप्रयुक्त volumes हटा सकते हैं:
प्रोडक्शन सेटअप के लिए, Docker ऐसे volume ड्राइवर्स सपोर्ट करता है जो NFS, AWS EFS या क्लाउड ब्लॉक स्टोरेज जैसे बाहरी स्टोरेज सिस्टम से कनेक्ट होते हैं। आप volume बनाते समय ड्राइवर निर्दिष्ट करते हैं, और बाकी Docker संभालता है। इससे आप डेटा पूरी तरह अपनी होस्ट मशीन के बाहर स्टोर कर सकते हैं, जो high-availability सेटअप्स में ज़रूरी होता है जहाँ कंटेनर सर्वरों के बीच स्थानांतरित होते हैं।
अब आगे, bind mounts पर चर्चा करते हैं।
लोकल डेवलपमेंट के लिए Bind Mounts
Bind mounts आपको कंटेनर के अंदर से सीधे आपके होस्ट फ़ाइलसिस्टम तक पहुँच देते हैं, और यही कारण है कि डेवलपर्स उन्हें पसंद करते हैं।
ये लोकल डेवलपमेंट के लिए परफेक्ट हैं लेकिन ऐसे trade-offs के साथ आते हैं जो उन्हें प्रोडक्शन के लिए जोखिमभरा बना देते हैं। आपको रीयल-टाइम फ़ाइल सिंक और ज़ीरो बिल्ड स्टेप्स मिलते हैं, लेकिन आप पोर्टेबिलिटी खो देते हैं और सुरक्षा में छेद खुल सकते हैं।
Bind mounts कैसे काम करते हैं
एक bind mount आपकी होस्ट मशीन की किसी विशिष्ट डायरेक्टरी को सीधे कंटेनर में मैप करता है।
आप सटीक पाथ निर्दिष्ट करते हैं - जैसे
/home/user/myapp- और Docker उसे कंटेनर के अंदर एक पाथ पर उपलब्ध करा देता है। इसमें कोई कॉपीिंग नहीं, कोई Docker-प्रबंधित स्टोरेज नहीं, कोई एब्स्ट्रैक्शन लेयर नहीं। कंटेनर आपकी वास्तविक होस्ट फ़ाइलें देखता है।यदि आप होस्ट पर कोई फ़ाइल बदलते हैं, तो कंटेनर तुरंत बदलाव देखता है। उसी तरह, यदि आप कंटेनर के अंदर कोई फ़ाइल संशोधित करते हैं, तो वह आपके होस्ट पर अपडेट हो जाती है। दोनों तरफ़ एक ही फ़ाइलों पर रीयल-टाइम में काम हो रहा होता है।
यहाँ bind mount का एक उदाहरण है:
यह मेरे होस्ट से
/Users/dradecic/Desktop/appको कंटेनर के अंदर/appपर माउंट करता है। जब मैं/Users/dradecic/Desktop/appमें किसी Python फ़ाइल को अपने टेक्स्ट एडिटर से एडिट करता हूँ, तो कंटेनराइज़्ड ऐप तुरंत बदलाव देख लेता है।आप छोटा सिंटैक्स भी उपयोग कर सकते हैं:
आम डेवलपमेंट वर्कफ़्लो
सबसे आम उपयोग-केस डेवलपमेंट के दौरान सोर्स कोड को माउंट करना है।
मान लीजिए आप FastAPI एप्लिकेशन बना रहे हैं। आप अपने प्रोजेक्ट डायरेक्टरी को कंटेनर में माउंट कर सकते हैं, hot reload सक्षम कर सकते हैं, और आपके पास पूर्ण डेवलपमेंट वातावरण तैयार है:
संदर्भ के लिए, यह मेरी
main.pyफ़ाइल है:Docker कमांड चलाने के बाद, ऐप मेरी होस्ट मशीन से पोर्ट 8000 पर उपलब्ध है:
यदि आप अपने एडिटर में
main.pyएडिट करके फ़ाइल सेव करते हैं, तो FastAPI स्वतः रीलोड हो जाएगा। कोई इमेज दोबारा बनानी नहीं, कोई कंटेनर रीस्टार्ट नहीं। आप स्थानीय की तरह कोड लिखते हैं, लेकिन आपका ऐप एक सुसंगत कंटेनर वातावरण में चलता है।जोखिम और सीमाएँ
Bind mounts आपके होस्ट फ़ाइलसिस्टम को कंटेनरों के सामने उजागर करते हैं, और इससे सुरक्षा समस्याएँ पैदा हो सकती हैं।
Bind mount वाला कंटेनर आपके होस्ट पर फ़ाइलें पढ़ और लिख सकता है। कंटेनर को root के रूप में चलाएँ - जो डिफ़ॉल्ट है - तो उसे उन माउंटेड फ़ाइलों पर root एक्सेस मिल जाता है। दुर्भावनापूर्ण कोड या समझौता किया गया कंटेनर माउंटेड डायरेक्टरी में कुछ भी संशोधित या हटा सकता है।
पोर्टेबिलिटी भी एक मुद्दा है।
Bind mounts होस्ट पर विशिष्ट पाथ्स के मौजूद होने पर निर्भर होते हैं।
/Users/dradecic/Desktop/appआपके सिस्टम या किसी प्रोडक्शन सर्वर पर मौजूद नहीं है। यह कंटेनरों के "हर जगह काम करता है" वादे को तोड़ देता है।प्लेटफ़ॉर्म भिन्नताएँ भी मायने रखती हैं। Windows और Mac, Docker चलाने के लिए VM का उपयोग करते हैं, इसलिए bind mounts एक अतिरिक्त ट्रांसलेशन लेयर से गुजरते हैं। इससे फ़ाइल ऑपरेशंस धीमे हो जाते हैं और फ़ाइल वॉचिंग व symlinks के साथ सूक्ष्म बग आ सकते हैं।
प्रोडक्शन वातावरण में bind mounts का कभी उपयोग नहीं करना चाहिए।
ये होस्ट-विशिष्ट पाथ्स पर बहुत अधिक निर्भर हैं, सुरक्षा के नज़रिए से जोखिमपूर्ण हैं, और version control में लाना असंभव है। Volumes इन सभी समस्याओं को हल करते हैं, और इसी वजह से वे प्रोडक्शन मानक हैं।
Bind mounts को डेवलपमेंट टूल की तरह मानें - तेज़, सुविधाजनक, और शक्तिशाली, लेकिन प्रोडक्शन के आस-पास भी नहीं।
अस्थायी डेटा के लिए tmpfs माउंट्स
tmpfs माउंट्स डेटा को आपकी होस्ट की RAM में स्टोर करते हैं, डिस्क पर नहीं। इससे वे ऐसे डेटा के लिए परफेक्ट हैं जिन्हें आप स्थायी नहीं रखना चाहते।
इन-मेमोरी स्टोरेज का व्यवहार
एक tmpfs माउंट पूरी तरह मेमोरी में मौजूद रहता है।
Docker आपकी होस्ट मशीन पर RAM आवंटित करता है और उसे कंटेनर के अंदर फ़ाइलसिस्टम के रूप में उपलब्ध कराता है। tmpfs माउंट पर लिखी फ़ाइल कभी डिस्क को नहीं छूती। डेटा, कंटेनर के रुकने तक मेमोरी में रहता है।
जब आप कंटेनर रोकते हैं, तो tmpfs माउंट में मौजूद सब कुछ हट जाता है। कोई क्लीनअप आवश्यक नहीं, कोई बचे हुए फ़ाइल नहीं, वहाँ क्या था इसका कोई निशान नहीं। हर बार कंटेनर रीस्टार्ट करने पर आपको नया, खाली tmpfs माउंट मिलता है।
संक्षेप में, tmpfs माउंट्स उस डेटा के लिए हैं जिसे आप जान-बूझकर नहीं रखना चाहते - अस्थायी गणनाएँ, सेशन टोकन, या ऐसा संवेदनशील डेटा जो उपयोग के बाद नहीं बचना चाहिए।
आम उपयोग-केस
सबसे आम उपयोग-केस secrets या संवेदनशील डेटा स्टोर करना है।
मान लीजिए आप ऐसा कंटेनर चला रहे हैं जिसे API key या डेटाबेस पासवर्ड चाहिए। इसे tmpfs माउंट में स्टोर करें, और secret कभी डिस्क पर स्टोर नहीं होगा। कंटेनर रुकते ही secret मेमोरी से गायब हो जाता है। कोई ऐसी फ़ाइल नहीं जिसे गलती से version control में commit कर दें या फ़ाइलसिस्टम पर खुली रह जाए।
कैश भी इसके लिए उपयुक्त हैं। build artifacts, compiled कोड, या डाउनलोड की गई dependencies जिन्हें आप वैसे भी दोबारा बनाएँगे, उन्हें persist होने की ज़रूरत नहीं। tmpfs में रखें ताकि कंटेनर के lifetime के दौरान तेज़ एक्सेस मिले, और काम ख़त्म होने पर उन्हें गायब होने दें।
अस्थायी फ़ाइलें भी यहाँ अच्छी तरह फिट बैठती हैं - जैसे सेशन डेटा, लॉक फ़ाइलें, या इंटरमीडिएट प्रोसेसिंग परिणाम जो केवल कंटेनर चलते समय मायने रखते हैं।
बेसिक कॉन्फ़िगरेशन
--tmpfsफ़्लैग का उपयोग करके tmpfs माउंट बनाने के लिए यह कमांड चलाएँ:यह कंटेनर के अंदर
/tmpपर 100MB का tmpfs माउंट बनाता है।sizeविकल्प यह सीमित करता है कि माउंट कितनी RAM उपयोग कर सकता है।आप
--mountसिंटैक्स भी उपयोग कर सकते हैं:tmpfs-sizeका मान bytes में होता है - 104857600 bytes यानी 100MB।यदि आप size लिमिट निर्दिष्ट नहीं करते, तो tmpfs आपके सिस्टम की आधी RAM तक उपयोग कर सकता है। यह खतरनाक है - कारण स्पष्ट हैं। हमेशा स्पष्ट size लिमिट सेट करें।
एक बड़ी कमी यह है कि tmpfs माउंट्स केवल Linux पर काम करते हैं।
Mac और Windows Docker Desktop इन्हें सपोर्ट नहीं करते क्योंकि वे Docker को Linux VM के अंदर चलाते हैं, और tmpfs को सीधे kernel सपोर्ट चाहिए।
Docker माउंट सिंटैक्स और कॉन्फ़िगरेशन
Docker आपको माउंट्स परिभाषित करने के दो तरीके देता है, और सही सिंटैक्स चुनने से आपकी कमांड्स पढ़ने और डिबग करने में आसान हो जाती हैं।
दोनों तरीके काम करते हैं, लेकिन जब आपको एडवांस्ड विकल्पों या एक ही कंटेनर में कई माउंट्स की ज़रूरत हो, तो एक तरीका बेहतर स्केल करता है।
-mount बनाम --volume
--mountफ़्लैग explicit key-value पेयर्स उपयोग करता है, जबकि-vया--volumecolon-सेपरेटेड स्ट्रिंग का उपयोग करता है।यहाँ एक ही volume माउंट दोनों सिंटैक्स में दिया है:
दोनों
mydataनामक एक volume बनाते हैं और उसे कंटेनर में/app/dataपर माउंट करते हैं।बेसिक सेटअप से आगे की किसी भी चीज़ के लिए
--mountका उपयोग करें। यह अधिक verbose है, लेकिन explicit keys यह स्पष्ट करती हैं कि हर भाग क्या करता है। जब आप read-only एक्सेस या कस्टम volume ड्राइवर्स जैसे विकल्प जोड़ते हैं, तो यह पढ़ने योग्य बना रहता है जबकि -v एक गूढ़ स्ट्रिंग जैसा लग सकता है।-vसिंटैक्स हाथ से टाइप की गई सरल डेवलपमेंट वर्कफ़्लो कमांड्स के लिए ठीक है।सामान्य माउंट विकल्प
readonlyविकल्प कंटेनरों को माउंटेड डेटा में संशोधन करने से रोकता है:यह कॉन्फ़िगरेशन फ़ाइलों या reference डेटा के लिए उपयोगी है जिन्हें कंटेनर पढ़ें लेकिन कभी बदलें नहीं। readonly माउंट पर लिखने की कोशिश करने वाला कंटेनर permission error पाता है।
Volumes के लिए,
volume-nocopyविकल्प कंटेनर इमेज से मौजूदा डेटा को volume में कॉपी करने को स्किप करता है:डिफ़ॉल्ट रूप से, Docker इमेज में माउंट पॉइंट पर जो भी मौजूद होता है, उसे नए volume में कॉपी कर देता है। जब आप
volume-nocopyसेट करते हैं, तो इमेज में क्या है इससे फर्क नहीं पड़ता, आपको खाली volume मिलता है।tmpfs माउंट्स के लिए,
tmpfs-sizeविकल्प मेमोरी लिमिट सेट करता है:यह tmpfs माउंट को 100MB पर कैप करता है। इसके बिना, tmpfs माउंट उपलब्ध सारी RAM खपा सकता है।
मौजूदा डेटा के ऊपर माउंट करना
जब आप कंटेनर इमेज में पहले से मौजूद किसी डायरेक्टरी पर माउंट करते हैं, तो माउंट वहाँ मौजूद हर चीज़ को पूरी तरह छिपा देता है।
मान लीजिए आपकी इमेज में
/app/dataडायरेक्टरी है जिसमें बिल्ट-इन कॉन्फ़िग फ़ाइलें हैं। जब आप/app/dataपर volume माउंट करते हैं, तो वे कॉन्फ़िग फ़ाइलें गायब हो जाएँगी। कंटेनर केवल volume में मौजूद चीज़ें ही देखेगा।यह सभी माउंट प्रकारों पर लागू होता है - volumes, bind mounts, और tmpfs। माउंटेड कंटेंट को प्राथमिकता मिलती है, और मूल डायरेक्टरी माउंट सक्रिय रहने तक अप्राप्य हो जाती है।
Docker Compose के साथ माउंट्स का उपयोग
Docker Compose आपके एप्लिकेशन स्टैक में कई कंटेनरों के बीच माउंट्स को परिभाषित और साझा करना आसान बनाता है।
लंबी
docker runकमांड्स के साथ माउंट फ़्लैग्स टाइप करने के बजाय, आप सब कुछdocker-compose.ymlफ़ाइल में घोषित करते हैं। मैं आपको दिखाता हूँ कैसे।Compose में volumes और bind mounts परिभाषित करना
यहाँ एक Compose फ़ाइल है जिसमें volume और bind mount दोनों के उदाहरण हैं:
volumesकी-के अंतर्गत हर सर्विस के लिए क्या माउंट होगा, यह परिभाषित होता है।./codeजैसे relative पाथ bind mounts बनाते हैं, जबकिsharedजैसे नाम नामित volumes को संदर्भित करते हैं।टॉप-लेवल
volumesसेक्शन उन नामित volumes की घोषणा करता है जिन्हें Compose बनाता और प्रबंधित करता है।service-1औरservice-2दोनों एक हीsharedvolume माउंट करते हैं, इसलिए वे एक जैसी फ़ाइलें देखते हैं। एक कंटेनर से फ़ाइल लिखें, और दूसरा कंटेनर उसे तुरंत पढ़ सकता है।sleep infinityकमांड कंटेनरों को चलता रखता है ताकि आप उनमें exec कर सकें - सिर्फ़ डेमो उद्देश्यों के लिए।डेटा को स्थायी रखना और सत्यापित करना
docker compose up -dसे अपना स्टैक शुरू करें, फिर जाँचें कि माउंट्स काम कर रहे हैं या नहीं:यदि दोनों कमांड काम करती हैं, तो आपके volumes सही तरह से कॉन्फ़िगर हैं।
अब आप यह कमांड चलाकर सब कुछ रोक और हटा सकते हैं:
आपके नामित volumes फिर भी मौजूद रहेंगे। यदि आप स्टैक को फिर
docker compose up -dसे शुरू करते हैं, तो पहले लिखा हुआ डेटा अब भी मौजूद रहेगा। इसी तरह डेटाबेस डिप्लॉयमेंट्स के पार बने रहते हैं - volume कंटेनर से अधिक समय तक जीवित रहता है।स्टैक को रोकते समय volumes हटाने के लिए -v फ़्लैग जोड़ें:
यह आपकी Compose फ़ाइल में परिभाषित सभी volumes हटा देता है। जब आप क्लीन स्लेट चाहते हैं, तब उपयोग करें।
शुरुआती डेटा के साथ volumes भरना
सबसे आम पैटर्न एक अलग init कंटेनर का उपयोग करके shared volume को seed करना है:
initकंटेनर seed डेटा बनाता है और उसे shared volume में कॉपी करता है, फिर बाहर निकलता है।service-1औरservice-2बाद में शुरू होते हैं और तैयार seeded डेटा पाते हैं।Compose, कई कंटेनरों और उनके shared स्टोरेज का समन्वय एक ही, version-controlled फ़ाइल में संभालता है।
Docker माउंट का प्रदर्शन और सुरक्षा
गलत माउंट प्रकार चुनने से आपके कंटेनर धीमे हो सकते हैं या ऐसे सुरक्षा छेद बन सकते हैं जिनका आपको पता भी न हो। यदि आप ऐसा नहीं चाहते, तो यह सेक्शन पढ़ें।
माउंट प्रकारों के बीच प्रदर्शन trade-offs
Linux पर volumes सबसे अच्छा प्रदर्शन देते हैं क्योंकि वे सीधे होस्ट फ़ाइलसिस्टम पर बिना किसी ट्रांसलेशन लेयर के स्टोर होते हैं।
Mac और Windows पर Docker एक Linux VM के अंदर चलता है। Volumes फिर भी अच्छा प्रदर्शन देते हैं क्योंकि वे उसी VM के भीतर रहते हैं। दूसरी ओर, bind mounts को आपके होस्ट OS और Linux VM के बीच फ़ाइलों को सिंक करना पड़ता है, जिससे overhead बढ़ता है। Mac और Windows पर bind mounts पर फ़ाइल ऑपरेशंस, native Linux की तुलना में काफी धीमे हो सकते हैं।
tmpfs पढ़ने और लिखने के लिए सबसे तेज़ विकल्प है क्योंकि सब कुछ RAM में होता है। कोई डिस्क I/O नहीं, कोई फ़ाइलसिस्टम overhead नहीं। लेकिन आप उपलब्ध मेमोरी से सीमित होते हैं, और कंटेनर रुकते ही डेटा गायब हो जाता है।
यदि आप Linux पर हैं और अधिकतम प्रदर्शन चाहिए, तो volumes का उपयोग करें। यदि आप Mac या Windows पर हैं और डेवलपमेंट के दौरान फ़ाइल ऑपरेशंस धीमे लगते हैं, तो संभवतः आप bind mount overhead का सामना कर रहे हैं। प्रोडक्शन वर्कलोड्स के लिए volumes पर स्विच करें।
माउंट्स के सुरक्षा निहितार्थ
हर माउंट कंटेनरों को उनके आइसोलेटेड फ़ाइलसिस्टम के बाहर किसी चीज़ तक पहुँच देता है, और इससे जोखिम पैदा होता है।
Bind mounts सबसे बड़ा चिंताजनक पहलू हैं। यदि आप
/home/userको कंटेनर में माउंट करते हैं, तो समझौता किया गया कंटेनर आपके SSH keys पढ़ सकता है, आपकी shell कॉन्फ़िग में बदलाव कर सकता है, या आपके पूरे home डायरेक्टरी में फ़ाइलें हटा सकता है। उसी कंटेनर को root के रूप में चलाएँ - जो डिफ़ॉल्ट है - तो उसे उन फ़ाइलों पर root-स्तरीय एक्सेस मिलता है।Volumes इस जोखिम को कम करते हैं क्योंकि वे Docker की स्टोरेज डायरेक्टरी में अलग-थलग रहते हैं। कंटेनर volumes के माध्यम से मनमाने होस्ट पाथ्स माउंट नहीं कर सकता। लेकिन यदि आप volumes को लापरवाही से साझा करते हैं, तो उनके जरिए कंटेनरों के बीच डेटा लीक हो सकता है।
tmpfs माउंट्स persistence जोखिम को न्यूनतम करते हैं - मेमोरी में स्टोर किए गए secrets कंटेनर रुकने पर गायब हो जाते हैं। लेकिन वे runtime हमलों से नहीं बचाते जहाँ समझौता किया गया कंटेनर मेमोरी से secrets पढ़ लेता है।
सामान्य नियम यह है कि माउंट्स कंटेनर आइसोलेशन को तोड़ते हैं, इसलिए उनका सावधानी से उपयोग करें।
सुरक्षित माउंट्स के लिए सर्वोत्तम प्रथाएँ
सिर्फ़ वही माउंट करें जिसकी कंटेनरों को आवश्यकता है, और उससे अधिक नहीं।
पूरी प्रोजेक्ट डायरेक्टरी माउंट करने के बजाय, केवल वही सबडायरेक्टरी माउंट करें जिसका कंटेनर उपयोग करता है।
/var/logको write एक्सेस के साथ माउंट करने के बजाय, यदि कंटेनर केवल लॉग पढ़ता है तो उसे read-only माउंट करें।जहाँ भी संभव हो,
readonlyविकल्प का उपयोग करें:यह कंटेनरों को माउंटेड डेटा में संशोधन करने से रोकता है, जिससे समझौता होने की स्थिति में नुकसान सीमित रहता है।
Bind mount कमजोरियों के प्रभाव को कम करने के लिए कंटेनरों को non-root उपयोगकर्ताओं के रूप में चलाएँ। अपने Dockerfile में एक उपयोगकर्ता बनाएँ और कंटेनर शुरू होने से पहले उस पर स्विच करें:
अप्रयुक्त volumes को नियमित रूप से
docker volume pruneके साथ साफ़ करें। पुराने volumes समय के साथ इकट्ठा हो जाते हैं, डिस्क स्पेस लेते हैं और हटाए गए कंटेनरों से संवेदनशील डेटा भी रख सकते हैं।कभी भी
/,/etcया/varजैसे संवेदनशील होस्ट डायरेक्टरीज़ को माउंट न करें, जब तक कि आपके पास कोई विशिष्ट कारण न हो और आप जोखिम समझते न हों। हर माउंट का एक स्पष्ट उद्देश्य और न्यूनतम दायरा होना चाहिए।Docker माउंट मुद्दों का ट्रबलशूटिंग
माउंट से जुड़ी समस्याएँ आमतौर पर परमिशन एरर्स, गायब फ़ाइलें, या कंटेनरों के शुरू न होने के रूप में दिखती हैं - और लगभग हमेशा वही कारण होते हैं।
यहाँ सबसे आम समस्याओं का निदान और समाधान कैसे करें:
परमिशन और ओनरशिप एरर्स
परमिशन एरर्स तब होती हैं जब कंटेनर के अंदर का उपयोगकर्ता माउंटेड फ़ाइलों तक पहुँच नहीं रखता।
Docker कंटेनर डिफ़ॉल्ट रूप से root के रूप में चलते हैं। जब root किसी bind mount में फ़ाइल बनाता है, तो वह फ़ाइल आपके होस्ट पर root की ओनरशिप रखती है। यदि आप उसे अपने सामान्य यूज़र अकाउंट से एडिट करने की कोशिश करेंगे, तो आपको permission denied एरर मिलेगा।
उल्टा भी होता है। जिस डायरेक्टरी के आप ओनर हैं उसे ऐसे कंटेनर में माउंट करें जो non-root यूज़र के रूप में चलता है, और हो सकता है कंटेनर उसमें लिख न सके।
माउंटेड डायरेक्टरी पर
ls -laचलाकर फ़ाइल ओनरशिप जाँच सकते हैं:यदि फ़ाइलें root की ओनरशिप में हैं लेकिन आपका कंटेनर किसी अन्य यूज़र के रूप में चलता है, तो mismatch है। इसे कंटेनर को उन्हीं यूज़र/ग्रुप IDs के साथ चलाकर ठीक करें जो फ़ाइलों की ओनरशिप से मेल खाते हैं:
यह कंटेनर को root के बजाय आपके वर्तमान यूज़र के रूप में चलाता है, जिससे bind mount में फ़ाइलों की ओनरशिप मैच होती है।
Volumes के लिए, जब कंटेनर फ़ाइलें बनाते हैं तो Docker परमिशन अपने आप संभालता है। लेकिन यदि एरर्स आ रही हैं, तो देखें कि कंटेनराइज़्ड ऐप किस यूज़र के रूप में चलता है और क्या उसे माउंट पॉइंट पर write एक्सेस है।
पाथ और कॉन्फ़िगरेशन की गलतियाँ
सबसे आम गलती होस्ट पर मौजूद न होने वाले पाथ को माउंट करना है।
यदि आप
/home/user/projectमाउंट करने की कोशिश करते हैं जबकि वह डायरेक्टरी मौजूद नहीं है, तो Docker root ओनरशिप वाली एक खाली डायरेक्टरी बना देगा। आपका कंटेनर शुरू हो जाएगा, लेकिन वह गलत चीज़ माउंट कर रहा होगा - आपकी वास्तविक प्रोजेक्ट के बजाय एक खाली डायरेक्टरी।हमेशा माउंट करने से पहले पाथ्स के अस्तित्व की पुष्टि करें:
यदि डायरेक्टरी मौजूद नहीं है, तो पहले उसे बनाएँ या अपनी माउंट कमांड में पाथ ठीक करें।
Docker Compose में, relative पाथ्स आपके
docker-compose.ymlफ़ाइल वाली डायरेक्टरी से रिज़ॉल्व होते हैं। यदि आपकी फ़ाइल/home/user/app/में है और आप./dataउपयोग करते हैं, तो Docker/home/user/app/dataढूँढता है।Compose फ़ाइल को कहीं और ले जाएँ, और माउंट टूट सकता है।
एक और आम गलती कंटेनर के अंदर गलत target पाथ पर माउंट करना है। यदि आपका ऐप
/dataअपेक्षा करता है और आप/app/dataपर माउंट करते हैं, तो ऐप अपनी फ़ाइलें नहीं ढूँढ पाएगा। अपने एप्लिकेशन के दस्तावेज़ या Dockerfile देखें कि उसे डेटा कहाँ चाहिए।प्लेटफ़ॉर्म-विशिष्ट विशेषताएँ
Linux पर bind mounts सीधे होस्ट फ़ाइलसिस्टम के साथ काम करते हैं।
Mac और Windows पर Docker एक Linux VM के अंदर चलता है। Bind mounts आपके होस्ट OS और उस VM के बीच फ़ाइलों को सिंक करते हैं, जिससे टाइमिंग इश्यूज आते हैं। फ़ाइल वॉचर्स - जो फ़ाइल बदलने पर आपके ऐप को रीलोड करते हैं - कभी-कभी सिंक देरी के कारण अपडेट मिस कर देते हैं।
Mac और Windows फ़ाइल परमिशन को अलग तरीके से संभालते हैं। VM होस्ट OS और Linux के बीच परमिशन का अनुवाद करता है, जिससे कंटेनरों के अंदर फ़ाइलें गलत ओनरशिप के साथ दिख सकती हैं।
Symlinks, Mac और Windows पर bind mounts में भरोसेमंद रूप से काम नहीं करते। VM हमेशा उन symlinks को resolve नहीं कर पाता जो माउंटेड डायरेक्टरी के बाहर की ओर इशारा करते हैं, इसलिए कंटेनरों के अंदर फ़ाइलें गायब या टूटी हुई दिख सकती हैं।
tmpfs माउंट्स Mac और Windows पर बिल्कुल काम नहीं करते क्योंकि VM, tmpfs को होस्ट तक एक्सपोज़ नहीं करता। यदि आप tmpfs माउंट का उपयोग करने की कोशिश करते हैं, तो Docker चुपचाप उसे नज़रअंदाज कर देगा या वर्ज़न पर निर्भर करते हुए एरर देगा।
यदि आप Mac या Windows पर डेवलपमेंट कर रहे हैं और अजीब फ़ाइल सिंक समस्याएँ आ रही हैं, तो बेहतर प्रदर्शन और विश्वसनीयता के लिए नामित volumes पर स्विच करें। Bind mounts को उन डेवलपमेंट वर्कफ़्लोज़ के लिए बचाकर रखें जहाँ रीयल-टाइम सिंक परफेक्ट सुसंगतता से अधिक मायने रखता है।
निष्कर्ष
समाप्त करते हुए, ऐसे प्रोडक्शन डेटा के लिए volumes का उपयोग करें जिसे बनाए रखना ज़रूरी है, जैसे डेटाबेस, अपलोड की गई फ़ाइलें, एप्लिकेशन स्टेट - यानी कुछ भी जिसे आप खो नहीं सकते। ये Docker-प्रबंधित हैं, प्लेटफ़ॉर्म्स के पार पोर्टेबल हैं, और महत्वपूर्ण डेटा के लिए सबसे सुरक्षित विकल्प हैं।
Bind mounts, डेवलपमेंट वर्कफ़्लोज़ के लिए उपयुक्त हैं जहाँ आपको होस्ट और कंटेनरों के बीच रीयल-टाइम फ़ाइल सिंक चाहिए। आप एडिटर में कोड एडिट करें, और कंटेनराइज़्ड ऐप में बदलाव तुरंत दिखें। लेकिन इन्हें प्रोडक्शन से दूर रखें क्योंकि ये होस्ट-विशिष्ट पाथ्स पर बहुत निर्भर हैं और अनावश्यक सुरक्षा जोखिम पैदा करते हैं।
जब आप कंटेनराइज़ेशन और वर्चुअलाइज़ेशन में और गहराई तक जाने के लिए तैयार हों, तो हमारा कोर्स देखें: Containerization and Virtualization with Docker and Kubernetes.