بستهٔ خصوصی‌ای که روی ماشین شما بی‌مشکل حل می‌شود می‌تواند درون ساخت با خطای 404 یا با پایان مهلت شکست بخورد، و Dockerfile به‌ندرت علت آن است. گام ساخت در فضای نام شبکهٔ دیگری اجرا می‌شود، با نمای DNS متفاوت و انبار اعتبارنامهٔ متفاوت از پوسته‌ای که در آن آزموده‌اید. این بررسی‌ها را به ترتیب انجام دهید و در نخستین موردی که شکست می‌خورد بایستید، زیرا هر بررسی بعدی فرض می‌کند بررسی پیشین گذشته است. هر گام فرمانی را نام می‌برد که کار را روشن می‌کند.

با نام بردن سازنده شروع کنید، نه Dockerfile

BuildKit می‌تواند محلی، درون کانتینر یا روی ماشین دیگری باشد و هر یک شبکهٔ پیش‌فرض خود را دارد. اجرا کنید docker buildx ls و پیش از هر تغییری گرهٔ ستاره‌دار را بخوانید. یک docker-container یا سازندهٔ ابری مسیر خصوصی روی لپ‌تاپ شما را فقط به این دلیل که فرمان را آنجا تایپ کرده‌اید به اشتراک نمی‌گذارد. اگر سازندهٔ فعال دور باشد، هر بررسی باقی‌مانده باید روی همان میزبان اجرا شود، نه روی ایستگاه کاری شما.

سازنده همچنین پیکربندی resolver و متغیرهای proxyخودش را حمل می‌کند. هر دو در زمان ساخت خوانده می‌شوند و از پایانه‌ای که ساخت را آغاز کرده به ارث نمی‌رسند.

مسیر شبکه را از درون یک گام ساخت اثبات کنید

مرحلهٔ یک‌بارمصرفی بنویسید که میزبان وابستگی را حل کند و به آن اتصال باز کند. این تنها آزمونی است که به پرسش برای سازنده پاسخ می‌دهد، نه برای پوستهٔ شما.

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/

آن فایل را با همان سازنده، همان حالت شبکه و همان سوارکردن‌های راز که ساخت واقعی‌تان به کار می‌برد بسازید: docker buildx build --builder remote0 -f Dockerfile.probe --progress=plain .. اگر getent چیزی چاپ نکند، خطا در حل نام است و هیچ اعتبارنامه‌ای آن را درست نمی‌کند. اگر نام حل شود ولی curl پایان مهلت را گزارش کند، مانع مسیر یا سیاست خروج پیش از رجیستری است.

پس از پاسخ دادن، کاوشگر را پاک کنید. این یک مرحلهٔ تشخیصی است و هرگز نباید برچسب بخورد یا push شود.

اعتبارنامه را سوار کنید، نه کپی

وقتی مسیر کار کرد، احراز هویت شکست بعدی در صف است. سوارکردن راز BuildKit یک فایل را به یک RUN گام عرضه می‌کند بدون نوشتن آن در یک لایه، و همین چیزی است که ابزار وابستگی نیاز دارد و تصویر نباید نگه دارد.

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

راز باید از بیرون Dockerfile تأمین شود: docker buildx build --secret id=npmrc,src=/home/me/.npmrc .. فایل نزد سرویس‌گیر می‌ماند و هرگز به تاریخچهٔ تصویر وارد نمی‌شود. یک ARG یا ENV با همان توکن این کار را نمی‌کند، زیرا هر دو در پیکربندی تصویر ثبت می‌شوند.

تصویر بدون root به مسیر مقصد خودش نیاز دارد، مانند /home/app/.npmrc یا فایل معادل برای pip، Maven یا Cargo. مقصد سوارکردن باید با کاربری که فرمان را اجرا می‌کند بخواند، وگرنه ابزار از فایل پیکربندی گمشده‌ای گزارش می‌دهد که در واقع آنجاست.

بررسی کنید ابزار وابستگی چه چیزی در تصویر جا می‌گذارد

سوارکردن موقت اعتبارنامه را بیرون از لایه نگه می‌دارد، ولی مانع نوشتن چیز دیگری توسط ابزار نمی‌شود. مدیران بسته فایل‌های lock، پوشه‌های cache و گاهی نشانی حل‌شدهٔ رجیستری را جا می‌گذارند.

به‌جای اعتماد به Dockerfile، فایل‌سیستم نهایی را بخوانید. docker history --no-trunc image:tag هر فرمان لایه را فهرست می‌کند، و docker run --rm image:tag sh -c "ls -a /root" نشان می‌دهد چه چیزی به کانتینر در حال اجرا رسیده است. حتی وقتی فایل فقط سوار شده بود، توکنی که هنگام npm ci در خط گزارش نوشته شود، هنوز نشت است.

گزارش ساخت را هم بخوانید، زیرا --progress=plain خروجی فرمان‌ها را عیناً چاپ می‌کند. اگر توکن آنجا پیدا شد، پیش از هر کار دیگری آن را بچرخانید و آن را از راه فایلی که ابزار بی‌صدا می‌خواند بگذرانید.

تأیید کنید که تصویر زمان اجرا دیگر به مسیر خصوصی نیاز ندارد

ساخت و برنامهٔ در حال اجرا دو مصرف‌کنندهٔ متفاوت از یک وابستگی‌اند و تنها اولی به مسیر خصوصی نیاز دارد. تصویر تمام‌شده باید بدون اعتبارنامهٔ ساخت آغاز شود، وابستگی‌های زمان اجرایش را حل کند و ترافیک را سرو کند.

آن را جایی بیازمایید که رجیستری خصوصی در دسترس نیست، یا کانتینر را ساده با --network none آغاز کنید و تأیید کنید که بدون راز سوارشده بالا می‌آید. کانتینری که فقط وقتی راز ساخت هست آغاز می‌شود، هنوز به محیط ساخت گره خورده است.

اگر کانتینر واقعاً در زمان اجرا به رجیستری نیاز دارد، این تصمیمی جداگانه دربارهٔ دسترسی است و جای آن انبار راز هماهنگ‌کننده است، نه ساخت. دو مسیر را جدا مستند کنید تا کسی نکوشد یک pull زمان اجرا را با پرچم ساخت تعمیر کند. وقتی هر پنج بررسی بگذرند، نشانهٔ اصلی در هر لایه علت نام‌دار دارد، نه حدسی دربارهٔ شبکهٔ Docker.

مقالات مرتبط