اس مسئلے کے بارے میں تقریباً ہر تحریر والیوم کو موردِ الزام ٹھہراتی ہے، اور اسی وجہ سے اصلاح میں اتنا وقت لگتا ہے۔ آپ کے پاس کام کرنے والا bind mount تھا، کارپوریٹ VPN منسلک ہوا، اور docker compose up اب غائب source path، خالی ڈائریکٹری، یا ایسے mount کے ساتھ ناکام ہوتا ہے جسے انجن بنانے سے انکار کرتا ہے۔ میں نے جن ماحولوں کو صاف کیا، ان میں Compose فائل تبدیل نہیں ہوئی تھی اور راستہ درست تھا۔ جو بدلا وہ یہ تھا کہ کون سے daemon کو درخواست ملی، اور mount کی خرابی صرف پہلی جگہ تھی جہاں یہ فرق نظر آیا۔

والیوم کبھی نہیں ہلا؛ درخواست ہلی

ایک -v /srv/app:/app flag آپ کے shell کی بنائی ہوئی ڈائریکٹری کاپی نہیں ہے۔ کلائنٹ اسے API درخواست میں بدلتا ہے، اور جواب دینے والا daemon /srv/app کو اپنے ہی فائل سسٹم کے مطابق حل کرتا ہے۔ جب دونوں طرف ایک ہی کرنل پر چلتے ہیں، تو وہی راستہ آپ کو فائل مینیجر میں نظر آتا ہے۔ جب endpoint بدلتا ہے، تو وہی سٹرنگ ایسی مشین پر تلاش کی جاتی ہے جس نے آپ کی پروجیکٹ ڈائریکٹری کے بارے میں کبھی نہیں سنا، اور daemon یا تو ماخذ کو غائب بتاتا ہے یا خاموشی سے اس کی جگہ خالی ڈائریکٹری بنا دیتا ہے۔

نام والا والیوم کام کرتا رہتا ہے جبکہ bind mount نہیں، اس کی وجہ بھی یہی ہے۔ -v appdata:/app daemon کی ملکیت والے اسٹوریج کو نام دیتا ہے، اس لیے کسی host path کا کسی مخصوص جگہ موجود ہونا ضروری نہیں۔ اگر ایک سروس کو bind mount سے نام والے والیوم میں بدلنے سے خرابی ختم ہو جائے، تو آپ نے مسئلہ درست نہیں کیا۔ آپ نے تصدیق کی ہے کہ کلائنٹ اور daemon اس بات پر متفق نہیں کہ راستہ کس فائل سسٹم کا ہے، اور یہ اختلاف اسی لمحے واپس آتا ہے جب آپ کو دوبارہ حقیقی host ڈائریکٹری درکار ہو۔

mount کو چھونے سے پہلے endpoint چھاپیں

کئی ترتیبات کلائنٹ کو endpoint کی طرف اشارہ کر سکتی ہیں، اور وہ ہمیشہ متفق نہیں ہوتیں: --context flag، DOCKER_CONTEXT، DOCKER_HOST موجودہ shell میں، اور کلائنٹ کنفیگریشن میں محفوظ context۔ ترجیح پر غور کرنے کے بجائے سب چھاپیں اور جوابات کا موازنہ کریں۔

docker context show
docker context ls
docker version
docker info --format "{{.Name}} {{.OperatingSystem}} {{.ServerVersion}}"

کلائنٹ کنفگ یہاں ہے: ~/.docker/config.json Linux اور macOS پر، اور یہاں: %USERPROFILE%\.docker\config.json Windows پر، اور موجودہ ٹرمینل میں export کی گئی قدر محفوظ قدر کو صرف اسی سیشن کے لیے اوور رائیڈ کرتی ہے۔ اگر endpoint مقامی socket کے بجائے hostname ہے، تو نام کا حل اور راستے طے کرتے ہیں کہ یہ کہاں اترے گا، اور VPN کلائنٹ ٹھیک یہی چیزیں دوبارہ لکھتا ہے۔ راستہ شامل کرنے یا resolver بدلنے والا tunnel ایسا نام، جو پہلے اس لیپ ٹاپ کے لیے تھا، کارپوریٹ نیٹ ورک کے اندر کے پتے پر بھیج سکتا ہے۔

کنفیگریشن کے بجائے حالت کا موازنہ کریں۔ tunnel بند ہونے پر docker ps -a اور docker images چلائیں، پھر tunnel کھلا ہونے پر دوبارہ۔ مختلف کنٹینر فہرست کسی بھی کنفگ فائل سے زیادہ مضبوط ثبوت ہے، کیونکہ یہ دکھاتی ہے کہ آپ کی درخواست کا جواب کسی دوسرے daemon نے دیا۔

daemon سے پوچھیں کہ کیا راستہ وہاں موجود ہے

جب آپ جان لیں کہ کس daemon تک پہنچے، تو اسے ڈائریکٹری دیکھنے دیں۔ --mount شکل مختصر flag کے مقابلے واضح پیغام کے ساتھ ناکام ہوتی ہے، کیونکہ یہ کنٹینر شروع کرنے سے پہلے ماخذ کی توثیق کرتی ہے:

docker run --rm --mount type=bind,source=/srv/app,target=/app alpine ls -la /app

اگر یہ ماخذ کو غائب بتائے، تو اسے جواب دینے والی مشین پر بنائیں، یا سروس کو نام والے والیوم کی طرف موڑ کر ڈیٹا وہاں کاپی کریں۔ جو آپ کو نہیں کرنا چاہیے وہ یہ ہے کہ اس جانچ سے پہلے والیوم دوبارہ بنائیں اور انجن دوبارہ انسٹال کریں۔ وہ اعمال ماحول کو اتنا بدل دیتے ہیں کہ عدم مطابقت چھپ جائے، مگر وہ اپنی جگہ پر رہتی ہے۔

ایک اور راستہ بالکل کہیں اور چلتا ہے: image کھینچنا daemon کا کام ہے، کلائنٹ کا نہیں۔ کامیاب کھینچ صرف یہ ثابت کرتی ہے کہ daemon کسی registry تک پہنچ سکتا ہے، اور کام کرنے والا bind mount صرف یہ کہ راستہ حل ہوا۔ ہر راستے کو وہیں جانچیں جہاں وہ واقعی چلتا ہے، ورنہ غلط راستے پر دوپہر ضائع کریں گے۔

انٹرانیٹ نام کسی اور وجہ سے ناکام ہوتے ہیں

اسی رپورٹ کا دوسرا نصف عام طور پر یہ ہوتا ہے کہ کنٹینر intranet.corp.exampleتک نہیں پہنچ سکتا۔ یہ الگ طریقہ کار ہے، دوسرا والیوم مسئلہ نہیں۔ کنٹینر کو اپنا /etc/resolv.conf شروع ہوتے وقت ملتا ہے، جو daemon resolver ترتیبات سے بنتا ہے، اس لیے کنٹینر بننے کے بعد VPN کا شامل کردہ DNS سرور کنٹینر دوبارہ بننے تک وہاں ظاہر نہیں ہوگا۔

صارف کی متعین نیٹ ورک پر Docker کا بلٹ اِن resolver بیرونی استفسارات host کے کنفیگر شدہ سرورز کو بھیجتا ہے، جو VPN کے host resolver دوبارہ لکھنے پر مدد کرتا ہے اور تقسیم شدہ DNS کے اندرونی زون کو ایسے سرور پر بھیجنے پر نقصان دیتا ہے جسے daemon اب نہیں دیکھتا۔ تنگ اور واضح میپنگ ان ناموں کے لیے بحث سے بچ جاتی ہے جو کبھی نہیں بدلتے:

services:
  web:
    extra_hosts:
      - "intranet.corp.example:10.20.30.40"

یہ کنٹینر کی hosts فائل میں اندراج لکھتا ہے، اس لیے کنٹینر tunnel کے بارے میں کچھ نہیں سیکھتا، اور پتہ بھی منجمد کر دیتا ہے۔ جب اندرونی host ہلے، تو اندراج غلط ہی رہتا ہے جب تک کوئی Compose فائل میں ترمیم نہ کرے۔ اسے مستقل آلے یا پن شدہ ڈیٹابیس کے لیے استعمال کریں، اور ہلنے والے نام DNS کے حوالے کر دیں۔

دوبارہ انسٹال اصل میں کیا بدلتا ہے

Docker Desktop دوبارہ انسٹال کرنے سے VM، socket اور context فہرست دوبارہ بنتی ہے، اور mount پھر کام کرنے لگتا ہے۔ وہ نتیجہ حقیقی ہے اور کچھ نہیں سکھاتا، اسی لیے اگلی VPN اپ ڈیٹ کے بعد وہی خرابی واپس آتی ہے۔ دوبارہ انسٹال نے وہ endpoint بدلا جو کلائنٹ استعمال کر رہا تھا؛ اس نے آپ کے پروجیکٹ کے نام کردہ راستے کو اس فائل سسٹم سے ہم آہنگ نہیں کیا جو daemon واقعی پڑھتا ہے۔

میرا کام کا ترتیب مختصر ہے۔ تصدیق کریں کہ کلائنٹ کون سا endpoint استعمال کرے گا۔ کنٹینر فہرستوں کا موازنہ کر کے تصدیق کریں کہ کون سے daemon نے جواب دیا۔ اس daemon سے source path کی فہرست دینے کو کہیں۔ اس کے بعد ہی mount میں ترمیم کریں، hosts اندراج شامل کریں، یا والیوم کی قسم بدلیں۔ اگر آپ VPN پر کام کرنے والی ٹیم کے لیے Compose فائل سنبھالتے ہیں، تو ایسے ڈیٹا کے لیے نام والے والیوم کو ترجیح دیں جو daemon کی ملکیت میں ہونا چاہیے، تاکہ host path کبھی معاہدے کا حصہ نہ بنے۔

متعلقہ مضامین