Docker build პირად დამოკიდებულებამდე ვერ აღწევს: შეამოწმეთ ეს
პირადი პაკეტი, რომელსაც ჰოსტი იღებს, მაინც შეიძლება ჩავარდეს build-ის შიგნით. დაასახელეთ builder, დაამტკიცეთ მარშრუტი და შემდეგ დაამაგრეთ ტოკენი build-საიდუმლოდ.
პირადი პაკეტი, რომელიც თქვენს მანქანაზე უპრობლემოდ იხსნება, build-ის შიგნით შეიძლება ჩავარდეს 404-ით ან დროის ამოწურვით, და Dockerfile იშვიათად არის მიზეზი. build-ის ნაბიჯი მუშაობს სხვა ქსელურ სახელთა სივრცეში, სხვა DNS ხედვით და სხვა სერტიფიკატების საცავით, ვიდრე ის shell, რომელშიც ტესტავდით. გაიარეთ ეს შემოწმებები თანმიმდევრობით და გაჩერდით პირველ ჩავარდნილზე, რადგან ყოველი შემდეგი შემოწმება ვარაუდობს, რომ წინა გავიდა. ყოველი ნაბიჯი ასახელებს ბრძანებას, რომელიც წყვეტს საკითხს.
დაიწყეთ builder-ის სახელით და არა Dockerfile-ით
BuildKit შეიძლება იყოს ლოკალური, კონტეინერში ან სხვა მანქანაზე, და თითოეულს აქვს თავისი ნაგულისხმევი ქსელი. გაუშვით docker buildx ls და წაიკითხეთ ვარსკვლავით მონიშნული კვანძი, სანამ რამეს შეცვლით. ერთი docker-container დრაივერი ან ღრუბლოვანი builder არ იზიარებს თქვენი ლეპტოპის პირად მარშრუტს მხოლოდ იმიტომ, რომ ბრძანება იქ აკრიფეთ. თუ აქტიური builder დისტანციურია, ყოველი დარჩენილი შემოწმება უნდა შესრულდეს იმ ჰოსტზე და არა თქვენს სამუშაო სადგურზე.
builder-ს ასევე აქვს თავისი resolver-ის კონფიგურაცია და proxy ცვლადები. ორივე იკითხება build-ის დროს და არ მემკვიდრეობით გადადის იმ ტერმინალიდან, რომელმაც build დაიწყო.
დაამტკიცეთ ქსელური გზა build-ის ნაბიჯის შიგნიდან
დაწერეთ ერთჯერადი ეტაპი, რომელიც ხსნის დამოკიდებულების ჰოსტს და ხსნის მასთან კავშირს. ეს ერთადერთი ტესტია, რომელიც პასუხობს კითხვას 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-ით, ქსელური რეჟიმით და იმავე საიდუმლო-დამაგრებებით, რომლებსაც თქვენი ნამდვილი build იყენებს: docker buildx build --builder remote0 -f Dockerfile.probe --progress=plain .. თუ getent არაფერს დაბეჭდავს, ხარვეზი სახელთა ამოხსნაშია და ვერც ერთი სერტიფიკატი ვერ გამოასწორებს. თუ სახელი იხსნება, მაგრამ curl დროის ამოწურვას იუწყება, დაბრკოლება მარშრუტია ან რეგისტრის წინ არსებული გასვლის პოლიტიკა.
წაშალეთ ზონდი, როგორც კი უპასუხებს. ეს დიაგნოსტიკური ეტაპია და არასოდეს უნდა მოინიშნოს ან გაიგზავნოს.
დაამაგრეთ სერტიფიკატი მისი კოპირების ნაცვლად
როცა გზა იმუშავებს, ავთენტიფიკაცია რიგში შემდეგი ჩავარდნაა. BuildKit-ის საიდუმლო-დამაგრება ფაილს ერთ RUN ნაბიჯს აძლევს, შრეში ჩაუწერელად; ეს სჭირდება დამოკიდებულების ხელსაწყოს და ეს არ უნდა შეინარჩუნოს image-მა.
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc npm ci --omit=dev
საიდუმლო უნდა მიეწოდოს Dockerfile-ის გარედან: docker buildx build --secret id=npmrc,src=/home/me/.npmrc .. ფაილი რჩება კლიენტთან და არასოდეს შედის image-ის ისტორიაში. ერთი ARG ან ENV იგივე ტოკენით ამ საქმეს არ ასრულებს, რადგან ორივე image-ის კონფიგურაციაში იწერება.
არა-root image-ს სჭირდება საკუთარი სამიზნე გზა, მაგალითად /home/app/.npmrc ან შესაბამისი ფაილი pip-ის, Maven-ის ან Cargo-სთვის. დამაგრების სამიზნე უნდა შეესაბამებოდეს ბრძანების გამშვებ მომხმარებელს, თორემ ხელსაწყო შეატყობინებს დაკარგულ კონფიგურაციის ფაილზე, რომელიც სინამდვილეში არსებობს.
შეამოწმეთ, რას ტოვებს დამოკიდებულების ხელსაწყო image-ში
დროებითი დამაგრება სერტიფიკატს შრის გარეთ ინახავს, მაგრამ ხელსაწყოს სხვა რამის ჩაწერას არ უშლის. პაკეტების მენეჯერები ტოვებენ lock ფაილებს, cache საქაღალდეებს და ზოგჯერ ამოხსნილ რეგისტრის URL-ს.
წაიკითხეთ დასრულებული ფაილური სისტემა Dockerfile-ის ნდობის ნაცვლად. docker history --no-trunc image:tag ჩამოთვლის ყოველ შრის ბრძანებას, და docker run --rm image:tag sh -c "ls -a /root" აჩვენებს, რა გადარჩა მოქმედ კონტეინერში. მაშინაც კი, როცა ფაილი მხოლოდ დამაგრებული იყო, ჟურნალის სტრიქონში ჩაწერილი ტოკენი npm ci დროსაც გაჟონვად რჩება.
წაიკითხეთ build-ის ჟურნალიც, რადგან --progress=plain ბრძანებების გამონატანს სიტყვასიტყვით ბეჭდავს. თუ ტოკენი იქ გამოჩნდა, ყველაფერზე ადრე შეცვალეთ ის და გადასცით ფაილის მეშვეობით, რომელსაც ხელსაწყო ჩუმად კითხულობს.
დარწმუნდით, რომ გაშვების image-ს აღარ სჭირდება პირადი გზა
build და მოქმედი აპლიკაცია ერთი და იმავე დამოკიდებულების ორი სხვადასხვა მომხმარებელია, და პირადი მარშრუტი მხოლოდ პირველს სჭირდება. დასრულებული image უნდა გაეშვას, ამოხსნას თავისი გაშვების დამოკიდებულებები და მოემსახუროს ტრაფიკს build-ის სერტიფიკატის გარეშე.
გამოსცადეთ იქ, სადაც პირადი რეგისტრი მიუწვდომელია, ან უბრალოდ გაუშვით კონტეინერი --network none და დაადასტურეთ, რომ ის იტვირთება დამაგრებული საიდუმლოს გარეშე. კონტეინერი, რომელიც ირთვება მხოლოდ მაშინ, როცა build-ის საიდუმლო არსებობს, ჯერ კიდევ build-ის გარემოსთან არის მიბმული.
თუ კონტეინერს ნამდვილად სჭირდება რეგისტრი გაშვების დროს, ეს ცალკე წვდომის გადაწყვეტილებაა და მისი ადგილი ორკესტრატორის საიდუმლოებათა საცავია და არა build. დააფიქსირეთ ორივე გზა ცალ-ცალკე, რათა არავინ შეეცადოს გაშვების დროის pull-ის გასწორებას build-ის დროშით. როცა ხუთივე შემოწმება გაივლის, საწყის სიმპტომს ყოველ შრეზე დასახელებული მიზეზი აქვს, და არა ვარაუდი Docker-ის ქსელზე.