आपकी मशीन पर बिना अड़चन के हल होने वाला निजी पैकेज build के भीतर 404 या टाइमआउट के साथ विफल हो सकता है, और Dockerfile शायद ही कभी इसका कारण होता है। build चरण किसी दूसरे नेटवर्क नेमस्पेस में चलता है, अलग DNS दृश्य और अलग क्रेडेंशियल स्टोर के साथ, जिस शेल में आपने परीक्षण किया था उससे अलग। इन जाँचों को क्रम से करें और पहली विफल जाँच पर रुक जाएँ, क्योंकि हर बाद की जाँच मानती है कि पिछली पास हुई है। हर चरण उस कमांड का नाम बताता है जो मामला तय करती है।

Dockerfile से नहीं, builder के नाम से शुरू करें

BuildKit स्थानीय, कंटेनर में या किसी दूसरी मशीन पर चल सकता है, और हर एक का अपना डिफ़ॉल्ट नेटवर्क होता है। चलाएँ docker buildx ls और कुछ भी बदलने से पहले तारांकित नोड पढ़ें। एक docker-container ड्राइवर या क्लाउड builder सिर्फ़ इसलिए आपके लैपटॉप का निजी मार्ग साझा नहीं करता कि आपने वह कमांड वहाँ लिखी थी। अगर सक्रिय builder दूरस्थ है, तो बाकी हर जाँच उसी होस्ट पर चलनी चाहिए, आपके वर्कस्टेशन पर नहीं।

builder अपना resolver कॉन्फ़िगरेशन और proxy चरभी साथ रखता है। दोनों build के समय पढ़े जाते हैं और उस टर्मिनल से विरासत में नहीं मिलते जिसने build शुरू किया।

build चरण के भीतर से नेटवर्क पथ सिद्ध करें

एक अस्थायी स्टेज लिखें जो निर्भरता के होस्ट को हल करे और उससे कनेक्शन खोले। यह एकमात्र परीक्षण है जो सवाल का जवाब builder के लिए देता है, आपके शेल के लिए नहीं।

FROM alpine:3.20
RUN apk add --no-cache curl bind-tools  && getent hosts registry.example.internal  && curl -sS -o /dev/null -w "%{http_code}
" https://registry.example.internal/simple/

उस फ़ाइल को उसी builder, नेटवर्क मोड और उन्हीं secret माउंट के साथ build करें जो आपका असली build इस्तेमाल करता है: docker buildx build --builder remote0 -f Dockerfile.probe --progress=plain .. अगर getent कुछ नहीं छापे, तो खराबी नाम-समाधान में है और कोई क्रेडेंशियल उसे ठीक नहीं करेगा। अगर नाम हल होता है पर curl टाइमआउट बताता है, तो अवरोध मार्ग या रजिस्ट्री के सामने की इग्रेस नीति है।

जवाब मिलते ही प्रोब हटा दें। यह नैदानिक स्टेज है और इसे कभी टैग या पुश नहीं करना चाहिए।

क्रेडेंशियल कॉपी करने के बजाय माउंट करें

मार्ग काम करने के बाद, प्रमाणीकरण अगली विफलता है। BuildKit secret माउंट एक फ़ाइल को एक RUN चरण तक खोलता है, उसे किसी लेयर में लिखे बिना; निर्भरता उपकरण को यही चाहिए और इमेज को यह नहीं रखना चाहिए।

RUN --mount=type=secret,id=npmrc,target=/root/.npmrc     npm ci --omit=dev

secret Dockerfile के बाहर से देना होगा: docker buildx build --secret id=npmrc,src=/home/me/.npmrc .. फ़ाइल क्लाइंट पर रहती है और कभी इमेज इतिहास में नहीं जाती। एक ARG या ENV उसी टोकन के साथ यह काम नहीं करते, क्योंकि दोनों इमेज कॉन्फ़िगरेशन में दर्ज होते हैं।

गैर-root इमेज को अपना लक्ष्य पथ चाहिए, जैसे /home/app/.npmrc या pip, Maven या Cargo के लिए समतुल्य फ़ाइल। माउंट लक्ष्य उस उपयोगकर्ता से मेल खाना चाहिए जो कमांड चलाता है, वरना उपकरण एक गुम कॉन्फ़िगरेशन फ़ाइल बताएगा जो असल में मौजूद है।

जाँचें कि निर्भरता उपकरण इमेज में क्या छोड़ता है

अस्थायी माउंट क्रेडेंशियल को लेयर से बाहर रखता है, पर उपकरण को कुछ और लिखने से नहीं रोकता। पैकेज प्रबंधक lock फ़ाइलें, cache निर्देशिकाएँ और कभी-कभी हल किया गया रजिस्ट्री URL छोड़ देते हैं।

Dockerfile पर भरोसा करने के बजाय तैयार फ़ाइलसिस्टम पढ़ें। docker history --no-trunc image:tag हर लेयर कमांड सूचीबद्ध करता है, और docker run --rm image:tag sh -c "ls -a /root" दिखाता है कि चल रहे कंटेनर में क्या बचा। यहाँ तक कि जब फ़ाइल केवल माउंट की गई थी, लॉग पंक्ति में लिखा टोकन npm ci के दौरान भी लीक ही रहता है।

build लॉग भी पढ़ें, क्योंकि --progress=plain कमांडों का आउटपुट शब्दशः छापता है। अगर टोकन वहाँ दिखे, तो बाकी सब से पहले उसे घुमाएँ और ऐसी फ़ाइल से भेजें जिसे उपकरण चुपचाप पढ़ता है।

सत्यापित करें कि रनटाइम इमेज को अब निजी मार्ग की ज़रूरत नहीं

build और चल रहा एप्लिकेशन एक ही निर्भरता के दो अलग उपभोक्ता हैं, और निजी मार्ग सिर्फ़ पहले को चाहिए। तैयार इमेज को build-समय के क्रेडेंशियल के बिना शुरू होना चाहिए, अपनी रनटाइम निर्भरताएँ हल करनी चाहिए और ट्रैफ़िक परोसना चाहिए।

इसे वहाँ परखें जहाँ निजी रजिस्ट्री पहुँच से बाहर है, या कंटेनर को बस --network none के साथ शुरू करें और पुष्टि करें कि वह माउंट किए गए secret के बिना बूट होता है। जो कंटेनर सिर्फ़ तब शुरू होता है जब build secret मौजूद हो, वह अब भी build परिवेश से जुड़ा है।

अगर कंटेनर को रनटाइम पर रजिस्ट्री सचमुच चाहिए, तो यह अलग पहुँच निर्णय है, और उसकी जगह ऑर्केस्ट्रेटर के secret स्टोर में है, build में नहीं। दोनों मार्ग अलग-अलग दर्ज करें ताकि कोई रनटाइम पुल को build फ़्लैग से ठीक करने की कोशिश न करे। जब पाँचों जाँच पास हो जाती हैं, तो मूल लक्षण के पीछे हर परत पर एक नामित कारण होता है, Docker नेटवर्किंग के बारे में अंदाज़ा नहीं।

संबंधित लेख