Build Docker tidak menjangkau dependensi privat: periksa ini
Paket privat yang bisa diambil host tetap bisa gagal di dalam build. Sebutkan builder, buktikan rutenya, lalu pasang token sebagai build secret.
Paket privat yang selesai diresolve tanpa masalah di mesin Anda bisa gagal di dalam build dengan 404 atau timeout, dan Dockerfile jarang menjadi penyebabnya. Langkah build berjalan di ruang nama jaringan yang berbeda, dengan pandangan DNS dan penyimpanan kredensial yang berbeda dari shell tempat Anda menguji. Jalankan pemeriksaan ini berurutan dan berhenti pada yang pertama gagal, karena setiap pemeriksaan berikutnya menganggap yang sebelumnya lolos. Setiap langkah menyebutkan perintah yang memutuskannya.
Mulailah dengan menyebut builder, bukan Dockerfile
BuildKit bisa lokal, dalam kontainer, atau di mesin lain, dan masing-masing punya jaringan bawaannya sendiri. Jalankan docker buildx ls dan baca node yang ditandai tanda bintang sebelum mengubah apa pun. Sebuah docker-container driver atau builder cloud tidak berbagi rute privat di laptop Anda hanya karena Anda mengetik perintahnya di sana. Jika builder aktif bersifat remote, setiap pemeriksaan berikutnya harus dijalankan terhadap host itu, bukan workstation Anda.
Builder juga membawa konfigurasi resolver dan variabel proxymiliknya sendiri. Keduanya dibaca saat build dan tidak diwarisi dari terminal yang memulai build.
Buktikan jalur jaringan dari dalam langkah build
Tulis tahap sekali pakai yang me-resolve host dependensi dan membuka koneksi ke sana. Ini satu-satunya uji yang menjawab pertanyaan untuk builder, bukan untuk shell Anda.
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/
Build berkas itu dengan builder, mode jaringan, dan pemasangan secret yang sama seperti build sungguhan Anda: docker buildx build --builder remote0 -f Dockerfile.probe --progress=plain .. Jika getent tidak mencetak apa pun, masalahnya ada pada resolusi nama dan tidak ada kredensial yang bisa memperbaikinya. Jika nama ter-resolve tetapi curl melaporkan timeout, penghalangnya adalah rute atau kebijakan keluar di depan registry.
Hapus probe begitu ia menjawab. Itu tahap diagnostik dan tidak boleh pernah diberi tag atau di-push.
Pasang kredensial alih-alih menyalinnya
Setelah jalur bekerja, autentikasi adalah kegagalan berikutnya. Pemasangan secret BuildKit mengekspos berkas ke satu langkah RUN tanpa menuliskannya ke lapisan, itulah yang dibutuhkan alat dependensi dan yang tidak boleh disimpan image.
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc npm ci --omit=dev
Secret harus dipasok dari luar Dockerfile: docker buildx build --secret id=npmrc,src=/home/me/.npmrc .. Berkas tetap di klien dan tidak pernah masuk riwayat image. Sebuah ARG atau ENV dengan token yang sama tidak melakukan pekerjaan ini, karena keduanya tercatat dalam konfigurasi image.
Image non-root membutuhkan jalur targetnya sendiri, misalnya /home/app/.npmrc atau berkas setara untuk pip, Maven, atau Cargo. Target pemasangan harus cocok dengan pengguna yang menjalankan perintah, atau alat akan melaporkan berkas konfigurasi yang hilang padahal sebenarnya ada.
Audit apa yang ditinggalkan alat dependensi di dalam image
Pemasangan sementara menjaga kredensial keluar dari lapisan, tetapi tidak menghentikan alat menulis hal lain. Manajer paket meninggalkan berkas lock, direktori cache, dan kadang URL registry yang sudah ter-resolve.
Baca sistem berkas hasil akhir alih-alih memercayai Dockerfile. docker history --no-trunc image:tag mendaftar setiap perintah lapisan, dan docker run --rm image:tag sh -c "ls -a /root" menunjukkan apa yang bertahan ke kontainer yang berjalan. Bahkan ketika berkas hanya dipasang, token yang ditulis ke baris log selama npm ci tetap merupakan kebocoran.
Baca juga log build, karena --progress=plain mencetak keluaran perintah apa adanya. Jika token muncul di sana, putar token itu sebelum hal lain dan lewatkan melalui berkas yang dibaca alat secara diam-diam.
Pastikan image runtime tidak lagi membutuhkan jalur privat
Build dan aplikasi yang berjalan adalah dua konsumen berbeda dari dependensi yang sama, dan hanya yang pertama membutuhkan rute privat. Image yang selesai harus bisa start, me-resolve dependensi runtime-nya, dan melayani lalu lintas tanpa kredensial build.
Uji di tempat registry privat tidak terjangkau, atau cukup jalankan kontainer dengan --network none dan pastikan ia boot tanpa secret yang dipasang. Kontainer yang hanya start ketika secret build tersedia masih terikat pada lingkungan build.
Jika kontainer memang membutuhkan registry saat runtime, itu keputusan akses tersendiri, dan tempatnya di penyimpanan secret orkestrator, bukan di build. Dokumentasikan kedua jalur secara terpisah agar tidak ada yang mencoba memperbaiki pull runtime dengan flag build. Ketika kelima pemeriksaan lolos, gejala aslinya punya penyebab bernama di setiap lapisan, bukan dugaan tentang jaringan Docker.