Un paquet privat que a la vostra màquina es resol sense problemes pot fallar dins de la build amb un 404 o un temps d’espera esgotat, i el Dockerfile poques vegades n’és la causa. El pas de build s’executa en un altre espai de noms de xarxa, amb una altra visió del DNS i un altre magatzem de credencials que la consola on heu provat. Recorreu aquestes comprovacions en ordre i atureu-vos a la primera que falli, perquè cada comprovació posterior dona per fet que l’anterior ha passat. Cada pas anomena l’ordre que ho resol.

Comenceu anomenant el builder, no el Dockerfile

BuildKit pot ser local, en contenidor o en una altra màquina, i cadascun té la seva xarxa per defecte. Executeu docker buildx ls i llegiu el node marcat amb un asterisc abans de canviar res. Un docker-container controlador o un builder al núvol no comparteix la ruta privada del vostre portàtil només perquè hi heu escrit l’ordre. Si el builder actiu és remot, cada comprovació restant s’ha d’executar contra aquest amfitrió i no contra la vostra estació de treball.

El builder també porta la seva pròpia configuració del resolutor i les seves variables de proxy. Totes dues es llegeixen en el moment de la build i no s’hereten del terminal que l’ha iniciada.

Demostreu el camí de xarxa des de dins d’un pas de build

Escriviu una etapa d’un sol ús que resolgui l’amfitrió de la dependència i hi obri una connexió. Aquesta és l’única prova que respon la pregunta pel builder i no per la vostra consola.

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/

Compileu aquest fitxer amb el mateix builder, mode de xarxa i muntatges de secrets que fa servir la vostra build real: docker buildx build --builder remote0 -f Dockerfile.probe --progress=plain .. Si getent no imprimeix res, la fallada és de resolució de noms i cap credencial no la repararà. Si el nom es resol però curl informa d’un temps d’espera esgotat, l’obstacle és la ruta o la política de sortida davant del registre.

Esborreu la sonda quan hagi contestat. És una etapa de diagnòstic i no s’ha d’etiquetar ni pujar mai.

Munteu la credencial en lloc de copiar-la

Quan la ruta funcioni, l’autenticació és la següent fallada de la llista. Un muntatge de secret de BuildKit exposa un fitxer a un sol pas RUN sense escriure’l en una capa, que és el que necessita l’eina de dependències i el que la imatge no ha de conservar.

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

El secret s’ha de fornir des de fora del Dockerfile: docker buildx build --secret id=npmrc,src=/home/me/.npmrc .. El fitxer es queda al client i no entra mai a l’historial de la imatge. Un ARG o una ENV que contingui el mateix testimoni no fan aquesta feina, perquè tots dos queden enregistrats a la configuració de la imatge.

Una imatge sense root necessita el seu propi camí de destí, com ara /home/app/.npmrc o el fitxer equivalent per a pip, Maven o Cargo. El destí del muntatge ha de correspondre a l’usuari que executa l’ordre, o l’eina informarà d’un fitxer de configuració absent que en realitat hi és.

Auditeu què deixa l’eina de dependències a la imatge

Un muntatge temporal manté la credencial fora d’una capa, però no impedeix que l’eina escrigui una altra cosa. Els gestors de paquets deixen fitxers de bloqueig, directoris de memòria cau i de vegades l’URL del registre resolta.

Llegiu el sistema de fitxers acabat en lloc de confiar en el Dockerfile. docker history --no-trunc image:tag llista cada ordre de capa, i docker run --rm image:tag sh -c "ls -a /root" mostra què ha sobreviscut al contenidor en marxa. Fins i tot quan el fitxer només s’ha muntat, un testimoni escrit en una línia de registre durant npm ci segueix sent una fuita.

Llegiu també el registre de build, perquè --progress=plain imprimeix la sortida de les ordres al peu de la lletra. Si el testimoni hi apareix, canvieu-lo abans que res més i passeu-lo per un fitxer que l’eina llegeixi en silenci.

Verifiqueu que la imatge d’execució ja no necessita la ruta privada

La build i l’aplicació en marxa són dos consumidors diferents de la mateixa dependència, i només el primer necessita la ruta privada. Una imatge acabada ha d’arrencar, resoldre les seves dependències d’execució i servir trànsit sense la credencial de build.

Proveu-ho on el registre privat no sigui abastable, o simplement inicieu el contenidor amb --network none i confirmeu que arrenca sense el secret muntat. Un contenidor que només arrenca quan el secret de build hi és encara està acoblat a l’entorn de build.

Si el contenidor realment necessita el registre en temps d’execució, és una decisió d’accés a part, i correspon al magatzem de secrets de l’orquestrador i no a la build. Documenteu els dos camins per separat perquè ningú intenti reparar una descàrrega d’execució amb un indicador de build. Quan les cinc comprovacions passen, el símptoma original té una causa anomenada a cada capa en lloc d’una conjectura sobre la xarxa de Docker.

Articles relacionats