Το build του Docker δεν φτάνει σε ιδιωτική εξάρτηση: ελέγξτε το
Ένα ιδιωτικό πακέτο που ο host κατεβάζει μπορεί να αποτύχει μέσα στο build. Ονομάστε τον builder, αποδείξτε τη διαδρομή και μετά προσαρτήστε το token ως build secret.
Ένα ιδιωτικό πακέτο που επιλύεται κανονικά στο μηχάνημά σας μπορεί να αποτύχει μέσα στο build με 404 ή με λήξη χρόνου, και το Dockerfile σπάνια είναι η αιτία. Το βήμα του build εκτελείται σε διαφορετικό network namespace, με διαφορετική όψη του DNS και διαφορετικό χώρο διαπιστευτηρίων από το shell όπου δοκιμάσατε. Περάστε αυτούς τους ελέγχους με τη σειρά και σταματήστε στον πρώτο που αποτυγχάνει, γιατί κάθε επόμενος έλεγχος προϋποθέτει ότι πέρασε ο προηγούμενος. Κάθε βήμα ονομάζει την εντολή που κρίνει το ζήτημα.
Ξεκινήστε ονομάζοντας τον builder, όχι το Dockerfile
Το BuildKit μπορεί να είναι τοπικό, σε container ή σε άλλο μηχάνημα, και καθένα έχει το δικό του προεπιλεγμένο δίκτυο. Εκτελέστε docker buildx ls και διαβάστε τον κόμβο που σημειώνεται με αστερίσκο πριν αλλάξετε οτιδήποτε. Ένας docker-container οδηγός ή ένας cloud builder δεν μοιράζεται την ιδιωτική διαδρομή στο laptop σας μόνο επειδή πληκτρολογήσατε εκεί την εντολή. Αν ο ενεργός builder είναι απομακρυσμένος, κάθε υπόλοιπος έλεγχος πρέπει να εκτελεστεί σε εκείνον τον host και όχι στον σταθμό εργασίας σας.
Ο builder κουβαλά και τη δική του ρύθμιση resolver και μεταβλητές proxy. Και τα δύο διαβάζονται τη στιγμή του build και δεν κληρονομούνται από το τερματικό που ξεκίνησε το build.
Αποδείξτε τη διαδρομή δικτύου μέσα από ένα βήμα build
Γράψτε ένα προσωρινό στάδιο που επιλύει τον host της εξάρτησης και ανοίγει σύνδεση προς αυτόν. Είναι το μόνο τεστ που απαντά στην ερώτηση για τον builder και όχι για το 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/
Χτίστε αυτό το αρχείο με τον ίδιο builder, το ίδιο network mode και τα ίδια secret mounts που χρησιμοποιεί το πραγματικό σας build: docker buildx build --builder remote0 -f Dockerfile.probe --progress=plain .. Αν getent δεν τυπώσει τίποτα, το πρόβλημα είναι στην επίλυση ονομάτων και κανένα διαπιστευτήριο δεν το διορθώνει. Αν το όνομα επιλυθεί αλλά το curl αναφέρει λήξη χρόνου, το εμπόδιο είναι η διαδρομή ή η πολιτική εξόδου μπροστά από το registry.
Διαγράψτε τον ανιχνευτή μόλις απαντήσει. Είναι διαγνωστικό στάδιο και δεν πρέπει ποτέ να δεχτεί tag ή push.
Προσαρτήστε το διαπιστευτήριο αντί να το αντιγράψετε
Όταν η διαδρομή δουλέψει, η επόμενη αποτυχία στη σειρά είναι η ταυτοποίηση. Ένα secret mount του BuildKit εκθέτει ένα αρχείο σε ένα RUN μόνο βήμα χωρίς να το γράψει σε layer, που είναι αυτό που χρειάζεται το εργαλείο εξαρτήσεων και αυτό που δεν πρέπει να κρατήσει το image.
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc npm ci --omit=dev
Το secret πρέπει να δοθεί από έξω από το Dockerfile: docker buildx build --secret id=npmrc,src=/home/me/.npmrc .. Το αρχείο μένει στον client και δεν μπαίνει ποτέ στο ιστορικό του image. Ένα ARG ή ENV με το ίδιο token δεν κάνουν αυτή τη δουλειά, γιατί και τα δύο καταγράφονται στη διαμόρφωση του image.
Ένα image χωρίς root χρειάζεται δική του διαδρομή προορισμού, όπως /home/app/.npmrc ή το αντίστοιχο αρχείο για pip, Maven ή Cargo. Ο προορισμός του mount πρέπει να ταιριάζει με τον χρήστη που εκτελεί την εντολή, αλλιώς το εργαλείο θα αναφέρει ένα αρχείο ρύθμισης που λείπει ενώ στην πραγματικότητα υπάρχει.
Ελέγξτε τι αφήνει το εργαλείο εξαρτήσεων μέσα στο image
Ένα προσωρινό mount κρατά το διαπιστευτήριο έξω από ένα layer, αλλά δεν εμποδίζει το εργαλείο να γράψει κάτι άλλο. Οι διαχειριστές πακέτων αφήνουν lock files, καταλόγους cache και μερικές φορές το URL του registry.
Διαβάστε το τελικό σύστημα αρχείων αντί να εμπιστεύεστε το Dockerfile. docker history --no-trunc image:tag απαριθμεί κάθε εντολή layer, και docker run --rm image:tag sh -c "ls -a /root" δείχνει τι επέζησε στο container που τρέχει. Ακόμα και όταν το αρχείο μόνο προσαρτήθηκε, ένα token γραμμένο σε γραμμή log κατά το npm ci παραμένει διαρροή.
Διαβάστε και το build log, γιατί --progress=plain τυπώνει την έξοδο των εντολών αυτολεξεί. Αν το token εμφανιστεί εκεί, περιστρέψτε το πριν από οτιδήποτε άλλο και περάστε το μέσα από ένα αρχείο που το εργαλείο διαβάζει ήσυχα.
Επιβεβαιώστε ότι το image εκτέλεσης δεν χρειάζεται πια την ιδιωτική διαδρομή
Το build και η εφαρμογή που τρέχει είναι δύο διαφορετικοί καταναλωτές της ίδιας εξάρτησης, και μόνο ο πρώτος χρειάζεται την ιδιωτική διαδρομή. Ένα ολοκληρωμένο image πρέπει να ξεκινά, να επιλύει τις εξαρτήσεις εκτέλεσής του και να εξυπηρετεί κίνηση χωρίς το διαπιστευτήριο του build.
Δοκιμάστε το εκεί όπου το ιδιωτικό registry δεν είναι προσβάσιμο, ή απλώς ξεκινήστε το container με --network none και επιβεβαιώστε ότι ξεκινά χωρίς το προσαρτημένο secret. Ένα container που ξεκινά μόνο όταν υπάρχει το build secret είναι ακόμα συνδεδεμένο με το περιβάλλον του build.
Αν το container χρειάζεται πραγματικά το registry στον χρόνο εκτέλεσης, αυτό είναι ξεχωριστή απόφαση πρόσβασης και ανήκει στο secret store του orchestrator και όχι στο build. Τεκμηριώστε τους δύο δρόμους χωριστά ώστε να μην προσπαθήσει κανείς να διορθώσει ένα runtime pull με ένα flag του build. Όταν περάσουν και οι πέντε έλεγχοι, το αρχικό σύμπτωμα έχει ονομασμένη αιτία σε κάθε επίπεδο αντί για εικασία για το δίκτυο του Docker.