Zasebni paket, ki se na vašem stroju razreši brez težav, lahko v build-u spodleti z napako 404 ali s časovno omejitvijo, in Dockerfile je redko vzrok. Korak build-a teče v drugem imenskem prostoru omrežja, z drugačnim pogledom na DNS in drugačnim skladiščem poverilnic kot lupina, v kateri ste testirali. Pojdite skozi te preveritve po vrsti in se ustavite pri prvi, ki spodleti, ker vsaka naslednja predpostavlja, da je prejšnja uspela. Vsak korak poimenuje ukaz, ki razreši vprašanje.

Začnite s poimenovanjem builderja, ne Dockerfile

BuildKit je lahko lokalen, v vsebniku ali na drugem stroju, in vsak ima svoje privzeto omrežje. Zaženite docker buildx ls in preberite vozlišče, označeno z zvezdico, preden karkoli spremenite. En docker-container gonilnik ali oblačni builder ne deli zasebne poti na vašem prenosniku samo zato, ker ste ukaz vpisali tam. Če je aktivni builder oddaljen, je treba vsako preostalo preveritev izvesti na tem gostitelju in ne na vaši delovni postaji.

Builder prinaša tudi svojo konfiguracijo resolverja in spremenljivke proxy. Oboje se prebere ob build-u in se ne podeduje iz terminala, ki je build zagnal.

Dokažite omrežno pot od znotraj koraka build-a

Napišite enkratno stopnjo, ki razreši gostitelja odvisnosti in odpre povezavo do njega. To je edini test, ki odgovori na vprašanje za builder in ne za vašo lupino.

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/

Zgradite to datoteko z istim builderjem, omrežnim načinom in istimi priklopi skrivnosti, kot jih uporablja vaš pravi build: docker buildx build --builder remote0 -f Dockerfile.probe --progress=plain .. Če getent ne izpiše ničesar, je napaka v razreševanju imen in nobene poverilnice je ne popravijo. Če se ime razreši, a curl poroča o časovni omejitvi, je ovira pot ali politika izhoda pred registrom.

Izbrišite sondo, takoj ko odgovori. To je diagnostična stopnja in je nikoli ne bi smeli označiti ali potisniti.

Pripnite poverilnico, namesto da bi jo kopirali

Ko pot deluje, je preverjanje pristnosti naslednja napaka v vrsti. Priklop skrivnosti v BuildKitu izpostavi datoteko enemu RUN koraku, ne da bi jo zapisal v plast, kar potrebuje orodje za odvisnosti in česar slika ne sme obdržati.

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

Skrivnost je treba zagotoviti zunaj Dockerfile: docker buildx build --secret id=npmrc,src=/home/me/.npmrc .. Datoteka ostane pri odjemalcu in nikoli ne vstopi v zgodovino slike. Niti ARG niti ENV z istim žetonom ne opravita tega dela, ker se oba zapišeta v konfiguracijo slike.

Slika brez root potrebuje svojo ciljno pot, na primer /home/app/.npmrc ali ustrezno datoteko za pip, Maven ali Cargo. Cilj priklopa se mora ujemati z uporabnikom, ki izvaja ukaz, sicer bo orodje poročalo o manjkajoči konfiguracijski datoteki, ki v resnici obstaja.

Preverite, kaj orodje za odvisnosti pusti v sliki

Začasen priklop drži poverilnico zunaj plasti, a orodju ne prepreči, da bi zapisalo kaj drugega. Upravitelji paketov pustijo lock datoteke, imenike predpomnilnika in včasih razrešen naslov registra.

Berite končni datotečni sistem, namesto da bi zaupali Dockerfile. docker history --no-trunc image:tag našteje vsak ukaz plasti, in docker run --rm image:tag sh -c "ls -a /root" pokaže, kaj je preživelo v delujočem vsebniku. Tudi kadar je bila datoteka samo pripeta, žeton, zapisan v vrstico dnevnika med npm ci ostane uhajanje.

Preberite tudi build dnevnik, ker --progress=plain izpiše izhod ukazov dobesedno. Če se žeton pojavi tam, ga zamenjajte pred vsem drugim in ga posredujte skozi datoteko, ki jo orodje bere tiho.

Prepričajte se, da izvajalna slika ne potrebuje več zasebne poti

Build in delujoča aplikacija sta dva različna uporabnika iste odvisnosti in zasebno pot potrebuje le prvi. Končna slika bi se morala zagnati, razrešiti svoje izvajalne odvisnosti in streči prometu brez poverilnic iz build-a.

Preizkusite to tam, kjer zasebni register ni dosegljiv, ali preprosto zaženite vsebnik z --network none in potrdite, da se zažene brez pripete skrivnosti. Vsebnik, ki se zažene le, kadar je prisotna build skrivnost, je še vedno povezan z okoljem build-a.

Če vsebnik register pri izvajanju res potrebuje, je to ločena odločitev o dostopu in spada v skladišče skrivnosti orkestratorja, ne v build. Dokumentirajte obe poti ločeno, da nihče ne poskuša popraviti izvajalnega pull-a z zastavico build-a. Ko vseh pet preveritev uspe, ima prvotni simptom na vsaki plasti poimenovan vzrok, namesto ugibanja o omrežju Docker.

Sorodni članki