Приватен пакет што на вашата машина се решава без проблем, во build може да не успее со 404 или со истек на времето, а Dockerfile ретко е причината. Чекорот на build работи во друг мрежен именски простор, со поинаков поглед на DNS и поинакво складиште на акредитиви од таа shell во која тестиравте. Поминате ги овие проверки по ред и застанете на првата што не успева, бидејќи секоја следна проверка претпоставува дека претходната поминала. Секој чекор ја именува командата што го решава прашањето.

Започнете со именување на builder, не на Dockerfile

BuildKit може да биде локален, во контејнер или на друга машина, и секој има своја стандардна мрежа. Извршете docker buildx ls и прочитајте го јазолот означен со ѕвездичка пред да промените нешто. Еден docker-container драјвер или облачен builder не ја дели приватната рута на вашиот лаптоп само затоа што командата ја напишавте таму. Ако активниот builder е оддалечен, секоја преостаната проверка мора да се изврши на тој домаќин, не на вашата работна станица.

Builder-от носи и своја конфигурација на resolver и proxy променливи. Двете се читаат за време на build и не се наследени од терминалот што го започнал build.

Докажете ја мрежната патека од внатрешноста на чекор од build

Напишете привремена фаза што го решава домаќинот на зависноста и отвора врска до него. Ова е единствениот тест што одговара на прашањето за builder, а не за вашата shell.

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, мрежен режим и истите тајни монтирања што ги користи вашиот вистински build: docker buildx build --builder remote0 -f Dockerfile.probe --progress=plain .. Ако getent не испечати ништо, дефектот е во решавањето на имиња и никакви акредитиви нема да го поправат. Ако името се реши, но curl пријави истек на времето, пречката е рутата или излезната политика пред регистарот.

Избришете ја сондата штом одговори. Тоа е дијагностичка фаза и никогаш не треба да биде означена или испратена.

Монтирајте ги акредитивите наместо да ги копирате

Кога патеката ќе проработи, автентикацијата е следниот неуспех во редот. Монтирањето тајна на BuildKit изложува датотека на еден RUN чекор без да ја запише во слој, тоа е што му треба на алатот за зависности и што image не смее да го задржи.

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

Тајната мора да се достави од надвор од Dockerfile: docker buildx build --secret id=npmrc,src=/home/me/.npmrc .. Датотеката останува кај клиентот и никогаш не влегува во историјата на image. Еден ARG или ENV со истиот токен не ја вршат оваа работа, бидејќи двете се запишуваат во конфигурацијата на image.

Image без root бара своја целна патека, на пример /home/app/.npmrc или соодветната датотека за pip, Maven или Cargo. Целта на монтирањето мора да одговара на корисникот што ја извршува командата, инаку алатот ќе пријави конфигурациска датотека што недостасува, а всушност е таму.

Проверете што остава алатот за зависности во image

Привременото монтирање ги држи акредитивите надвор од слој, но не го спречува алатот да напише нешто друго. Менаџерите на пакети оставаат lock датотеки, кеш директориуми и понекогаш решената регистарска URL.

Читајте го готовиот датотечен систем наместо да му верувате на Dockerfile. docker history --no-trunc image:tag ги набројува сите команди на слојот, а docker run --rm image:tag sh -c "ls -a /root" покажува што преживеало во контејнерот што работи. Дури и кога датотеката била само монтирана, токен запишан во линија од логот за време на npm ci сѐ уште е истекување.

Прочитајте го и build логот, бидејќи --progress=plain го печати излезот на командите буквално. Ако токенот се појави таму, заменете го пред се друго и предадете го преку датотека што алатот ја чита тивко.

Проверете дека image-от за извршување повеќе не ја бара приватната патека

Build и апликацијата што работи се два различни потрошувачи на истата зависност, и само првиот ја бара приватната рута. Готовиот image треба да стартува, да ги реши своите зависности за извршување и да служи сообраќај без акредитивите од build.

Тестирајте го таму каде приватниот регистар е недостапен, или едноставно стартувајте го контејнерот со --network none и потврдете дека се подига без монтираната тајна. Контејнер што стартува само кога е присутна build тајната сѐ уште е поврзан со build околината.

Ако на контејнерот навистина му треба регистарот при извршување, тоа е одделна одлука за пристап и ѝ е местото во складиштето за тајни на оркестраторот, а не во build. Документирајте ги двете патеки одделно за да не се обиде некој да го поправи извлекувањето при извршување со build знаменце. Кога сите пет проверки ќе поминат, првичниот симптом има именувана причина на секој слој наместо претпоставка за Docker мрежата.

Поврзани статии