Privatus paketas, kuris jūsų mašinoje išsprendžiamas be problemų, build metu gali nepavykti su 404 arba laiko limitu, ir Dockerfile retai būna priežastis. Build žingsnis vykdomas kitoje tinklo vardų erdvėje, su kitu DNS vaizdu ir kita prisijungimo duomenų saugykla nei ta shell, kurioje testavote. Peržiūrėkite šiuos patikrinimus iš eilės ir sustokite ties pirmuoju, kuris nepavyksta, nes kiekvienas vėlesnis patikrinimas daro prielaidą, kad ankstesnis praėjo. Kiekvienas žingsnis įvardija komandą, kuri išsprendžia klausimą.

Pradėkite nuo builder įvardijimo, o ne Dockerfile

BuildKit gali būti vietinis, konteineryje arba kitoje mašinoje, ir kiekvienas turi savo numatytąjį tinklą. Paleiskite docker buildx ls ir perskaitykite žvaigždute pažymėtą mazgą prieš ką nors keisdami. Vienas docker-container tvarkyklė ar debesų builder nesidalija privataus maršruto jūsų nešiojamajame kompiuteryje vien todėl, kad ten įvedėte komandą. Jei aktyvus builder yra nutolęs, kiekvienas likęs patikrinimas turi būti vykdomas tame hoste, o ne jūsų darbo stotyje.

Builder taip pat turi savo resolver konfigūraciją ir proxy kintamuosius. Abu skaitomi build metu ir nėra paveldimi iš terminalo, kuris paleido build.

Įrodykite tinklo kelią iš build žingsnio vidaus

Parašykite vienkartinį etapą, kuris išsprendžia priklausomybės hostą ir atidaro su juo ryšį. Tai vienintelis testas, kuris atsako į klausimą builderiui, o ne jūsų 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/

Sukompiliuokite tą failą su tuo pačiu builder, tinklo režimu ir tais pačiais paslapčių prijungimais, kuriuos naudoja jūsų tikrasis build: docker buildx build --builder remote0 -f Dockerfile.probe --progress=plain .. Jei getent nieko neišspausdina, gedimas yra vardų sprendime ir jokie prisijungimo duomenys jo neištaisys. Jei vardas išsprendžiamas, bet curl praneša apie laiko limitą, kliūtis yra maršrutas arba išėjimo politika prieš registrą.

Ištrinkite zondą, kai tik jis atsakys. Tai diagnostinis etapas, ir jo niekada nereikėtų žymėti ar stumti.

Prijunkite prisijungimo duomenis, o ne kopijuokite juos

Kai kelias veikia, autentifikavimas yra kita nesėkmė eilėje. BuildKit paslapties prijungimas atskleidžia failą vienam RUN žingsniui jo neįrašydamas į sluoksnį; to reikia priklausomybių įrankiui ir to image neturi išsaugoti.

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

Paslaptis turi būti tiekiama už Dockerfile ribų: docker buildx build --secret id=npmrc,src=/home/me/.npmrc .. Failas lieka kliente ir niekada nepatenka į image istoriją. Vienas ARG ar ENV su tuo pačiu token neatlieka šio darbo, nes abu įrašomi į image konfigūraciją.

Image be root turi savo tikslo kelią, pavyzdžiui /home/app/.npmrc arba atitinkamą failą pip, Maven ar Cargo. Prijungimo tikslas turi atitikti vartotoją, kuris vykdo komandą, kitaip įrankis praneš apie trūkstamą konfigūracijos failą, kuris iš tikrųjų yra.

Patikrinkite, ką priklausomybių įrankis palieka image

Laikinas prijungimas laiko prisijungimo duomenis už sluoksnio ribų, bet nesustabdo įrankio įrašyti ką nors kita. Paketų tvarkyklės palieka lock failus, podėlio katalogus ir kartais išspręstą registro URL.

Skaitykite baigtą failų sistemą, o ne pasitikėkite Dockerfile. docker history --no-trunc image:tag išvardija kiekvieną sluoksnio komandą, o docker run --rm image:tag sh -c "ls -a /root" parodo, kas išliko veikiančiame konteineryje. Net jei failas buvo tik prijungtas, token rašomas į žurnalo eilutę per npm ci vis tiek lieka nuotėkiu.

Perskaitykite ir build žurnalą, nes --progress=plain spausdina komandų išvestį pažodžiui. Jei token ten pasirodo, pakeiskite jį prieš visa kita ir perduokite per failą, kurį įrankis tyliai skaito.

Patvirtinkite, kad vykdymo image nebereikia privataus kelio

Build ir veikianti programa yra du skirtingi tos pačios priklausomybės vartotojai, ir privataus kelio reikia tik pirmajam. Baigtas image turėtų paleisti, išspręsti savo vykdymo priklausomybes ir aptarnauti srautą be build prisijungimo duomenų.

Išbandykite ten, kur privatus registras nepasiekiamas, arba tiesiog paleiskite konteinerį su --network none ir patvirtinkite, kad jis paleidžiamas be prijungtos paslapties. Konteineris, kuris paleidžiamas tik kai yra build paslaptis, vis dar susietas su build aplinka.

Jei konteineriui tikrai reikia registro vykdymo metu, tai atskiras prieigos sprendimas, ir jo vieta yra orkestratoriaus paslapčių saugykloje, o ne build. Dokumentuokite du kelius atskirai, kad niekas nebandytų taisyti vykdymo metu atliekamo pull su build vėliavėle. Kai visi penki patikrinimai praeina, pirminis simptomas turi įvardytą priežastį kiekviename sluoksnyje, o ne spėjimą apie Docker tinklą.

Susiję straipsniai