Seorang pembangun junior telah mengurangkan saiz imej Docker Python daripada 1.2 GB kepada 85 MB, memendekkan saluran paip CI daripada 11 minit kepada 90 saat. Imej yang lebih kecil dimuat turun dengan lebih cepat, kos penyimpanan lebih rendah, dan mendedahkan lebih sedikit kelemahan keselamatan.
Mengapa saiz imej penting
Setiap kali kontena ditarik (pulled), registry akan menyalurkan keseluruhan imej. Lapisan (layer) 85 MB tiba dalam beberapa saat; lapisan 1.2 GB boleh mengambil masa beberapa minit pada rangkaian yang sederhana. Ejen binaan (build agents) juga mesti memuat naik dan menyimpan cache imej penuh, yang meningkatkan masa CI dan bil storan awan. Setiap pakej tambahan adalah potensi kerentanan, jadi mengecilkan asas (base) akan mengurangkan permukaan serangan (attack surface).
Dari mana datangnya pembaziran (bloat)
- Alatan binaan seperti gcc kekal dalam imej akhir jika ia dipasang dalam peringkat yang sama dengan aplikasi yang dijalankan.
- Cache pengurus pakej (contohnya, cache
aptataupip) berada di dalam cakera dan tidak pernah dibersihkan secara lalai. - Setiap arahan
RUNmencipta lapisan baca-sahaja (read-only) yang baharu; fail yang bertindih merentasi lapisan akan bertambah. - Imej asas yang besar seperti
ubuntu:latestdisertakan dengan OS yang lengkap, jauh lebih banyak daripada yang diperlukan oleh runtime Python yang minimal.
Pengecilan tiga langkah
| Langkah | Imej asas | Pendekatan binaan | Saiz hasil |
|---|---|---|---|
| 1 | Python Standard (penuh) | Peringkat tunggal, semua alatan tersedia | 1.18 GB |
| 2 | python:slim |
Pelbagai peringkat: pembina dengan gcc, peringkat akhir hanya menyalin pakej yang telah dikompil | 210 MB |
| 3 | python:alpine |
Pelbagai peringkat pada Alpine Linux, yang mana ia sendiri sangat kecil | 85 MB |
Langkah 1 – garis dasar (baseline)
Bermula dengan imej Python lalai, pembangun melihat artifak sebesar 1.18 GB. Imej tersebut mengandungi stack Debian yang lengkap, pengepala pembangunan (development headers), dan cache pip.
Langkah 2 – slim dengan pembina (builder)
Bertukar kepada python:slim mengurangkan jejak OS, tetapi alatan binaan masih kekal. Menambah peringkat pembina (builder) membolehkan gcc, make, dan kebergantungan masa-kompil (compile-time dependencies) yang lain dipasang, dikompil, dan kemudian dihapuskan. Peringkat akhir menggunakan COPY --from=builder untuk menarik hanya wheels yang telah dikompil dan fail runtime, mengurangkan saiz kepada 210 MB.
Langkah 3 – Alpine menang
Alpine Linux dibina berasaskan musl libc dan busybox. Mengulangi corak pelbagai peringkat pada Alpine menghasilkan imej 85 MB—pengurangan sebanyak 93% daripada yang asal. Pembangun menyatakan bahawa Kubernetes menarik imej tersebut dalam beberapa saat dan tugasan CI selesai dalam 90 saat.
Impak dunia nyata
- Kos storan lebih rendah – Storan registry mengecil.
- Keselamatan dipertingkatkan – Pakej yang lebih sedikit bermakna lebih sedikit CVE untuk dijejak. Imej Alpine hanya mengandungi runtime Python dan kod aplikasi.
- CI lebih pantas – Masa larian saluran paip jatuh daripada 11 minit kepada 90 saat.
Tip praktikal untuk mengecilkan Dockerfile anda
- Elakkan tag
:latest; pilih varian:slimatau:alpineyang sesuai dengan keperluan anda. - Gunakan binaan pelbagai peringkat (multi-stage builds): peringkat pembina (builder) khusus untuk kompilasi, dan peringkat runtime yang hanya menerima artifak yang anda perlukan sahaja.
- Salin secara terpilih dengan
COPY --from=builder /path/to/installed /path/in/final. - Susun arahan supaya pemasangan kebergantungan dijalankan sebelum menyalin kod sumber; ini memaksimumkan caching lapisan.
- Bersihkan cache secara eksplisit, contohnya,
rm -rf /var/lib/apt/lists/* ~/.cache/pip.
Jika anda menggunakan Alpine, tambah pakej nss apabila aplikasi anda mengalami masalah resolusi DNS. Semasa memasang dengan pip, tambah /root/.local/bin ke dalam PATH supaya skrip yang dipasang secara tempatan dapat ditemui semasa masa larian (runtime).
Amaran (Caveats)
musl libc pada Alpine boleh bercanggah dengan binary wheels yang dikompil untuk glibc, menyebabkan ralat masa larian. Dalam kes tersebut, bina semula wheels di dalam pembina Alpine atau kembali menggunakan asas slim. Pakej nss tambahan adalah harga yang kecil untuk kebolehpercayaan DNS.
Apa yang perlu diperhatikan seterusnya
- Imbas imej sedia ada anda untuk mencari lapisan besar yang mungkin calon untuk penulisan semula pelbagai peringkat.
- Pantau log CI untuk masa muat naik dan muat turun bagi mengesan pembaziran imej.
- Perhatikan laporan kerentanan untuk pengedaran asas yang anda pilih.
Pengajarannya jelas: Dockerfile yang berdisiplin, asas yang ringan, dan peringkat pembina boleh mengecilkan imej Python dengan lebih daripada satu magnitud, memberikan manfaat kelajuan dan kos yang nyata tanpa mengorbankan fungsi.
