Прыватны пакет, які на вашай машыне развязваецца без праблем, можа праваліцца ўнутры зборкі з памылкай 404 або па тайм-аўце, і Dockerfile рэдка бывае прычынай. Крок зборкі выконваецца ў іншай сеткавай прасторы імёнаў, з іншым прадстаўленнем DNS і іншым сховішчам уліковых даных, чым абалонка, у якой вы тэставалі. Прайдзіце гэтыя праверкі па парадку і спыніцеся на першай няўдалай, бо кожная наступная мяркуе, што папярэдняя прайшла. Кожны крок называе каманду, якая вырашае пытанне.

Пачніце з назвы будаўніка, а не Dockerfile

BuildKit можа быць лакальным, у кантэйнеры або на іншай машыне, і кожны з іх мае сваю сетку па змаўчанні. Выканайце docker buildx ls і прачытайце вузел, пазначаны зорачкай, перш чым нешта змяняць. Драйвер docker-container або хмарны будаўнік не атрымлівае прыватны маршрут на вашым ноўтбуку толькі таму, што вы набралі каманду там. Калі актыўны будаўнік выдалены, усе астатнія праверкі трэба выконваць на тым хасце, а не на вашай працоўнай станцыі.

Будаўнік таксама мае ўласныя наладкі рэзалвера і зменныя проксі. Абодва чытаюцца падчас зборкі і не наследуюцца ад тэрмінала, які запускаў зборку.

Дакажыце сеткавы шлях знутры кроку зборкі

Напішыце часовую стадыю, якая развяжа хост залежнасці і адкрые да яго злучэнне. Гэта адзіны тэст, які адказвае на пытанне для будаўніка, а не для вашай абалонкі.

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 паведамляе пра тайм-аўт, перашкодай з’яўляецца маршрут або палітыка выхаду перад рэестрам.

Выдаліце зонд, як толькі ён адкажа. Гэта дыягнастычная стадыя, і яе нельга ні пазначаць тэгам, ні адпраўляць.

Падключайце ўліковыя даныя, а не капіруйце іх

Калі шлях працуе, наступная няўдача — аўтэнтыфікацыя. Мантаж сакрэту 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-файлы, каталогі кэша і часам развязаны URL рэестра.

Чытайце гатовую файлавую сістэму замест таго, каб давяраць Dockerfile. docker history --no-trunc image:tag пералічвае кожную каманду слая, а docker run --rm image:tag sh -c "ls -a /root" паказвае, што перажыло ў працуючым кантэйнеры. Нават калі файл быў толькі смантаваны, токен, запісаны ў радок лога npm ci усё роўна застаецца ўцечкай.

Чытайце таксама лог зборкі, бо --progress=plain друкуе вывад каманд даслоўна. Калі токен там з’яўляецца, змяніце яго раней за ўсё іншае і перадавайце праз файл, які інструмент чытае ціха.

Пераканайцеся, што вобраз часу выканання больш не мае патрэбы ў прыватным шляху

Зборка і працуючая праграма — два розныя спажыўцы адной залежнасці, і толькі першаму патрэбны прыватны маршрут. Гатовы вобраз павінен запускацца, развязваць свае залежнасці часу выканання і абслугоўваць трафік без уліковых даных зборкі.

Праверце гэта там, дзе прыватны рэестр недаступны, або проста запусціце кантэйнер з --network none і пераканайцеся, што ён загружаецца без смантаванага сакрэту. Кантэйнер, які запускаецца толькі пры наяўнасці сакрэту зборкі, усё яшчэ звязаны з асяроддзем зборкі.

Калі кантэйнеру рэестр сапраўды патрэбны падчас выканання, гэта асобнае рашэнне аб доступе, і яго месца ў сховішчы сакрэтаў аркестратара, а не ў зборцы. Апішыце два шляхі асобна, каб ніхто не спрабаваў выправіць спампоўку часу выканання сцягам зборкі. Калі ўсе пяць праворак праходзяць, першапачатковы сімптом мае названую прычыну на кожным узроўні замест здагадкі пра сетку Docker.

Падобныя артыкулы