Docker-build når ikke frem til en privat avhengighet: sjekk dette
En privat pakke som verten får tak i, kan likevel feile inne i builden. Navngi builderen, bevis ruten og monter deretter tokenet som en build-hemmelighet.
En privat pakke som løses uten problemer på maskinen din, kan feile inne i builden med en 404 eller en tidsavbrudd, og Dockerfile er sjelden årsaken. Build-trinnet kjører i et annet nettverksnavnerom, med et annet DNS-bilde og et annet lager for påloggingsinformasjon enn skallet du testet i. Gå gjennom disse kontrollene i rekkefølge og stopp ved den første som feiler, fordi hver senere kontroll forutsetter at den forrige gikk gjennom. Hvert trinn navngir kommandoen som avgjør saken.
Start med å navngi builderen, ikke Dockerfile
BuildKit kan være lokalt, i en container eller på en annen maskin, og hver av dem har sitt eget standardnettverk. Kjør docker buildx ls og les noden som er merket med en stjerne, før du endrer noe. En docker-container driver eller en skybuilder deler ikke den private ruten på laptopen din bare fordi du skrev kommandoen der. Hvis den aktive builderen er ekstern, må hver gjenværende kontroll kjøres mot den verten og ikke mot arbeidsstasjonen din.
Builderen har også sin egen resolver-konfigurasjon og proxy-variabler. Begge leses ved build-tid og arves ikke fra terminalen som startet builden.
Bevis nettverksveien inne fra et build-trinn
Skriv et engangstrinn som slår opp verten for avhengigheten og åpner en forbindelse til den. Dette er den eneste testen som svarer på spørsmålet for builderen og ikke for skallet ditt.
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/
Bygg den filen med samme builder, nettverksmodus og de samme secret-monteringene som den virkelige builden din bruker: docker buildx build --builder remote0 -f Dockerfile.probe --progress=plain .. Hvis getent ikke skriver ut noe, ligger feilen i navneoppslaget og ingen påloggingsinformasjon retter det. Hvis navnet løses, men curl rapporterer tidsavbrudd, er hindringen ruten eller egress-policyen foran registeret.
Slett sonden så snart den svarer. Det er et diagnostisk trinn og bør aldri tagges eller pushes.
Monter påloggingsinformasjonen i stedet for å kopiere den
Når ruten virker, er autentisering den neste feilen i rekken. En BuildKit secret-montering eksponerer en fil for ett RUN trinn uten å skrive den til et lag, og det er det avhengighetsverktøyet trenger og det image ikke må beholde.
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc npm ci --omit=dev
Hemmeligheten må leveres fra utsiden av Dockerfile: docker buildx build --secret id=npmrc,src=/home/me/.npmrc .. Filen blir værende hos klienten og kommer aldri inn i image-historikken. En ARG eller ENV med samme token gjør ikke denne jobben, fordi begge registreres i image-konfigurasjonen.
Et image uten root trenger sin egen målsti, for eksempel /home/app/.npmrc eller den tilsvarende filen for pip, Maven eller Cargo. Monteringsmålet må samsvare med brukeren som kjører kommandoen, ellers rapporterer verktøyet en manglende konfigurasjonsfil som faktisk er der.
Gå gjennom hva avhengighetsverktøyet legger igjen i image
En midlertidig montering holder påloggingsinformasjonen utenfor et lag, men den hindrer ikke verktøyet i å skrive noe annet. Pakkehåndterere legger igjen lock-filer, cache-kataloger og noen ganger den oppløste register-URL-en.
Les det ferdige filsystemet i stedet for å stole på Dockerfile. docker history --no-trunc image:tag lister hver lagkommando, og docker run --rm image:tag sh -c "ls -a /root" viser hva som overlevde inn i den kjørende containeren. Selv når filen bare ble montert, er et token skrevet i en logglinje under npm ci fortsatt en lekkasje.
Les også build-loggen, fordi --progress=plain skriver ut kommandoens utdata ordrett. Hvis tokenet dukker opp der, roter det før alt annet og send det gjennom en fil som verktøyet leser stille.
Bekreft at runtime-imaget ikke lenger trenger den private ruten
Builden og applikasjonen som kjører er to ulike forbrukere av samme avhengighet, og bare den første trenger den private ruten. Et ferdig image bør starte, løse sine runtime-avhengigheter og betjene trafikk uten build-påloggingsinformasjonen.
Test det der det private registeret ikke er tilgjengelig, eller start containeren ganske enkelt med --network none og bekreft at den starter uten den monterte hemmeligheten. En container som bare starter når build-hemmeligheten er til stede, er fortsatt koblet til build-miljøet.
Hvis containeren virkelig trenger registeret ved runtime, er det en egen tilgangsbeslutning, og den hører hjemme i orkestratorens secret store og ikke i builden. Dokumenter de to veiene hver for seg, slik at ingen prøver å reparere en runtime-pull med et build-flagg. Når alle fem kontrollene består, har det opprinnelige symptomet en navngitt årsak på hvert lag i stedet for en gjetning om Docker-nettverk.