Docker-bygget når inte fram till ett privat beroende: kontrollera detta
Ett privat paket som värden kan hämta kan ändå misslyckas inne i bygget. Namnge buildern, bevisa rutten och montera sedan token som en build-hemlighet.
Ett privat paket som löses utan problem på din maskin kan misslyckas inne i bygget med en 404 eller en tidsgräns, och Dockerfile är sällan orsaken. Byggsteget körs i ett annat nätverksnamnrum, med en annan DNS-vy och ett annat lager för inloggningsuppgifter än det skal du testade i. Gå igenom dessa kontroller i ordning och stanna vid den första som misslyckas, eftersom varje senare kontroll förutsätter att den föregående gick igenom. Varje steg namnger kommandot som avgör saken.
Börja med att namnge buildern, inte Dockerfile
BuildKit kan vara lokalt, i en container eller på en annan maskin, och var och en har sitt eget standardnätverk. Kör docker buildx ls och läs noden som är markerad med en stjärna innan du ändrar något. En docker-container drivrutin eller en molnbyggare delar inte den privata rutten på din laptop bara för att du skrev kommandot där. Om den aktiva buildern är fjärran måste varje återstående kontroll köras mot den värden och inte mot din arbetsstation.
Buildern bär också sin egen resolverkonfiguration och proxyvariabler. Båda läses vid byggtid och ärvs inte från terminalen som startade bygget.
Bevisa nätverksvägen inifrån ett byggsteg
Skriv ett engångssteg som slår upp beroendets värd och öppnar en anslutning till den. Det är det enda testet som svarar på frågan för buildern och inte för ditt skal.
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 samma builder, nätverksläge och samma secret-monteringar som ditt riktiga bygge använder: docker buildx build --builder remote0 -f Dockerfile.probe --progress=plain .. Om getent inget skrivs ut ligger felet i namnmatchningen och inga inloggningsuppgifter rättar det. Om namnet löses men curl rapporterar en tidsgräns är hindret rutten eller egress-policyn framför registret.
Radera sonden så snart den svarar. Det är ett diagnostiskt steg och bör aldrig taggas eller pushas.
Montera inloggningsuppgiften i stället för att kopiera den
När rutten fungerar är autentisering nästa fel i kön. En BuildKit secret-montering exponerar en fil för ett enda RUN steg utan att skriva den till ett lager, och det är vad beroendeverktyget behöver och vad image inte får behålla.
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc npm ci --omit=dev
Hemligheten måste levereras utanför Dockerfile: docker buildx build --secret id=npmrc,src=/home/me/.npmrc .. Filen stannar hos klienten och hamnar aldrig i image-historiken. En ARG eller ENV med samma token gör inte det här jobbet, eftersom båda registreras i image-konfigurationen.
En image utan root behöver sin egen målväg, till exempel /home/app/.npmrc eller motsvarande fil för pip, Maven eller Cargo. Monteringsmålet måste matcha användaren som kör kommandot, annars rapporterar verktyget en saknad konfigurationsfil som faktiskt finns där.
Granska vad beroendeverktyget lämnar kvar i imagen
En tillfällig montering håller inloggningsuppgiften utanför ett lager, men den hindrar inte verktyget från att skriva något annat. Pakethanterare lämnar lock-filer, cachemappar och ibland den upplösta register-URL:en.
Läs det färdiga filsystemet i stället för att lita på Dockerfile. docker history --no-trunc image:tag listar varje lagerkommando, och docker run --rm image:tag sh -c "ls -a /root" visar vad som överlevde in i den körande containern. Även när filen bara monterades finns en token som skrivs i en loggrad under npm ci kvar som en läcka.
Läs också byggloggen, eftersom --progress=plain skriver ut kommandots utdata ordagrant. Om token dyker upp där ska du rotera den före allt annat och skicka den genom en fil som verktyget läser tyst.
Bekräfta att runtime-imagen inte längre behöver den privata rutten
Bygget och applikationen som körs är två olika konsumenter av samma beroende, och bara den första behöver den privata rutten. En färdig image bör starta, lösa sina runtime-beroenden och betjäna trafik utan byggets inloggningsuppgifter.
Testa det där det privata registret inte går att nå, eller starta helt enkelt containern med --network none och bekräfta att den startar utan den monterade hemligheten. En container som bara startar när bygghemligheten finns är fortfarande kopplad till byggmiljön.
Om containern verkligen behöver registret vid runtime är det ett separat åtkomstbeslut, och det hör hemma i orkestrerarens secret store och inte i bygget. Dokumentera de två vägarna var för sig så att ingen försöker reparera en runtime-pull med en byggflagga. När alla fem kontrollerna passerar har det ursprungliga symptomet en namngiven orsak på varje lager i stället för en gissning om Docker-nätverk.