सामान्यतया, होस्ट वॉल्यूम माउंट के साथ अनुमतियाँ समस्याएँ होती हैं क्योंकि कंटेनर के अंदर uid / gid के पास फ़ाइल की पहुँच होस्ट के अनुसार फ़ाइल की uid / gid अनुमतियों के अनुसार नहीं होती है। हालाँकि, यह विशिष्ट मामला अलग है।
अनुमति स्ट्रिंग के अंत में स्थित drwxr-xr-x.
, इंगित करता है कि SELinux कॉन्फ़िगर किया गया है। SELinux के साथ होस्ट माउंट का उपयोग करते समय, आपको वॉल्यूम परिभाषा के अंत में एक अतिरिक्त विकल्प पास करना होगा:
z
विकल्प इंगित करता है कि सामग्री के लिए बाध्य माउंट कई कंटेनर के बीच साझा किया जाता है।
Z
विकल्प इंगित करता है कि सामग्री के लिए बाध्य माउंट निजी और साझा नहीं की है।
आपका वॉल्यूम माउंट कमांड तब दिखेगा:
sudo docker run -i -v /data1/Downloads:/Downloads:z ubuntu bash
SELinux के होस्ट होस्टों के बारे में अधिक जानकारी के लिए देखें: https://docs.docker.com/storage/#configure-the-selinux-label
दूसरों के लिए जो इस मुद्दे को एक अलग उपयोगकर्ता के रूप में चल रहे कंटेनरों के साथ देखते हैं, आपको यह सुनिश्चित करने की आवश्यकता है कि कंटेनर के अंदर उपयोगकर्ता के यूआईडी / gid को होस्ट पर फ़ाइल की अनुमति है। उत्पादन सर्वरों पर, यह अक्सर छवि निर्माण प्रक्रिया में यूआईडी / जीआईडी को नियंत्रित करके होस्ट पर एक यूआईडी / जीआईडी से मिलान करने के लिए किया जाता है, जिसकी फाइलों तक पहुंच होती है (या इससे भी बेहतर, उत्पादन में होस्ट माउंट का उपयोग नहीं करते हैं)।
एक नामित वॉल्यूम को अक्सर आरोहित होस्ट करने के लिए पसंद किया जाता है क्योंकि यह छवि निर्देशिका से वॉल्यूम निर्देशिका को आरंभ करेगा, जिसमें कोई फ़ाइल स्वामित्व और अनुमतियाँ शामिल हैं। यह तब होता है जब वॉल्यूम खाली होता है और कंटेनर को नामित वॉल्यूम के साथ बनाया जाता है।
MacOS उपयोगकर्ताओं के पास अब OSXFS है जो मैक होस्ट और कंटेनरों के बीच स्वचालित रूप से uid / gid को हैंडल करता है। एक जगह जिसके साथ यह मदद नहीं करता है वह एम्बेडेड वीएम के अंदर की फाइलें हैं जो कंटेनर में घुड़सवार होती हैं, जैसे /var/lib/docker.sock।
विकास के वातावरण के लिए, जहाँ होस्ट यूआईडी / जीआईडी प्रति डेवलपर बदल सकता है, मेरा पसंदीदा समाधान कंटेनर को रूट के रूप में चलाने वाले एंट्रीपॉइंट के साथ शुरू करना है, होस्ट वॉल्यूम यूआईडी / जीआईडी से मिलान करने के लिए कंटेनर के अंदर उपयोगकर्ता के यूआईडी / जीआईडी को ठीक करना, और फिर gosu
कंटेनर के अंदर एप्लिकेशन को चलाने के लिए कंटेनर उपयोगकर्ता को रूट से ड्रॉप करने के लिए उपयोग करें। इसके लिए महत्वपूर्ण स्क्रिप्ट fix-perms
मेरी आधार छवि लिपियों में है, जो यहां देखी जा सकती है: https://github.com/sudo-bmitch/docker-base
fix-perms
स्क्रिप्ट से महत्वपूर्ण बिट है:
# update the uid
if [ -n "$opt_u" ]; then
OLD_UID=$(getent passwd "${opt_u}" | cut -f3 -d:)
NEW_UID=$(stat -c "%u" "$1")
if [ "$OLD_UID" != "$NEW_UID" ]; then
echo "Changing UID of $opt_u from $OLD_UID to $NEW_UID"
usermod -u "$NEW_UID" -o "$opt_u"
if [ -n "$opt_r" ]; then
find / -xdev -user "$OLD_UID" -exec chown -h "$opt_u" {} \;
fi
fi
fi
कंटेनर के अंदर उपयोगकर्ता की फ़ाइल, और फ़ाइल के यूआईडी से यूआईडी प्राप्त होता है, और यदि वे मेल नहीं खाते हैं, usermod
तो यूआईडी को समायोजित करने के लिए कॉल करता है। अंत में यह उन फ़ाइलों को ठीक करने के लिए एक पुनरावर्ती खोज करता है जो यूआईडी नहीं बदले हैं। मुझे -u $(id -u):$(id -g)
ध्वज के साथ कंटेनर चलाने से बेहतर यह पसंद है क्योंकि उपरोक्त प्रविष्टि बिंदु कोड को कंटेनर को शुरू करने के लिए प्रत्येक डेवलपर को स्क्रिप्ट चलाने की आवश्यकता नहीं है, और उपयोगकर्ता के स्वामित्व वाले वॉल्यूम के बाहर की किसी भी फाइल को उनकी अनुमति सही होगी।
आप एक डैम को बांधने वाले नाम वाले वॉल्यूम का उपयोग करके किसी छवि से एक होस्ट निर्देशिका को प्रारंभ कर सकते हैं। यह निर्देशिका पहले से मौजूद होनी चाहिए, और आपको किसी कंपोज़ फ़ाइल में होस्ट वॉल्यूम के विपरीत होस्ट निर्देशिका के लिए एक पूर्ण पथ प्रदान करना होगा, जो सापेक्ष पथ हो सकते हैं। इसे आरंभ करने के लिए निर्देशिका को docker के लिए खाली होना चाहिए। बाइंड माउंट देखने के लिए नामांकित वॉल्यूम को परिभाषित करने के लिए तीन अलग-अलग विकल्प जैसे:
# create the volume in advance
$ docker volume create --driver local \
--opt type=none \
--opt device=/home/user/test \
--opt o=bind \
test_vol
# create on the fly with --mount
$ docker run -it --rm \
--mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=none,volume-opt=o=bind,volume-opt=device=/home/user/test \
foo
# inside a docker-compose file
...
volumes:
bind-test:
driver: local
driver_opts:
type: none
o: bind
device: /home/user/test
...
अंत में, यदि आप उपयोगकर्ता नामस्थानों का उपयोग करने का प्रयास करते हैं, तो आप पाएंगे कि होस्ट संस्करणों के पास अनुमति के मुद्दे हैं क्योंकि कंटेनरों के uid / gid को स्थानांतरित कर दिया गया है। इस परिदृश्य में, मेजबान संस्करणों से बचना संभव है और केवल नामांकित संस्करणों का उपयोग करें।