Baris FROM menetapkan image dasar, image yang menjadi fondasi seluruh layer, lapisan penyusun image, di atasnya. Pilihan image dasar menentukan ukuran image akhir, kompatibilitas dependensi, serta jumlah paket yang perlu dijaga keamanannya. Topik ini membandingkan varian image resmi Python, mulai dari varian penuh, varian slim yang dipangkas, varian alpine yang berbasis pustaka C ringan, hingga image distroless yang hanya memuat runtime, komponen yang menjalankan aplikasi. Perbandingannya disertai pengukuran ukuran terkompresi secara nyata. Bagian akhir merangkum rekomendasi praktis untuk aplikasi catatan Python yang menjadi contoh jalur ini.
Varian image resmi Python#
Image resmi Python di Docker Hub diterbitkan dalam beberapa varian dengan isi yang berbeda. Varian python:3.12 berbasis Debian penuh, lengkap dengan manajer paket apt, shell, dan banyak utilitas bawaan, sehingga menjadi yang terbesar. Varian python:3.12-slim tetap berbasis Debian tetapi dipangkas, sehingga pip, shell, dan pustaka yang benar-benar dibutuhkan Python tetap ada, sedangkan dokumentasi dan utilitas tambahan dibuang. Varian python:3.12-alpine berbasis Alpine Linux yang memakai musl, pustaka C ringan alternatif, alih-alih glibc, pustaka C GNU yang menjadi standar Debian, sehingga ukurannya paling kecil. Di luar ketiganya, image distroless menyediakan pendekatan paling ekstrem, yaitu tanpa shell, tanpa manajer paket, dan hanya berisi runtime Python beserta pustakanya.
Perbedaan isi itu tidak terlihat dari sintaks Dockerfile, karena keempatnya sama-sama dipakai lewat satu baris FROM. Perbedaannya baru muncul pada ukuran unduhan, perilaku pemasangan dependensi, dan alat yang tersedia saat diagnosis, sebagaimana diukur dan dibahas pada bagian berikutnya.
Ukuran terkompresi ketiga varian#
Perbedaan ketiga varian resmi itu terlihat nyata pada ukuran terkompresinya, yaitu beban unduhan yang muncul saat image ditarik dari registry, gudang image yang melayani unduhan dan unggahan. API Docker Hub melaporkannya melalui properti full_size setiap tag, sebagaimana sudah dicoba pada topik audit ukuran image.
curl -s "https://hub.docker.com/v2/repositories/library/python/tags/3.12" \
| python3 -c "import json,sys; data=json.load(sys.stdin); print('python:3.12 :', round(data['full_size']/1000000, 1), 'MB')"
curl -s "https://hub.docker.com/v2/repositories/library/python/tags/3.12-slim" \
| python3 -c "import json,sys; data=json.load(sys.stdin); print('python:3.12-slim :', round(data['full_size']/1000000, 1), 'MB')"
curl -s "https://hub.docker.com/v2/repositories/library/python/tags/3.12-alpine" \
| python3 -c "import json,sys; data=json.load(sys.stdin); print('python:3.12-alpine :', round(data['full_size']/1000000, 1), 'MB')"python:3.12 : 411.8 MB
python:3.12-slim : 43.3 MB
python:3.12-alpine : 18.0 MBVarian slim hampir sepuluh kali lebih kecil daripada varian penuh, sedangkan varian alpine kurang dari separuh ukuran slim. Selisih ini sudah ada sebelum satu instruksi Dockerfile pun dieksekusi, sehingga pilihan FROM menetapkan ukuran minimum sejak awal. Instruksi berikutnya, misalnya pemasangan paket dan penyalinan berkas aplikasi, menaikkan angka itu lebih jauh. Angka-angka di atas adalah cuplikan pada saat topik ini ditulis, karena nilainya berpindah setiap tag dibangun ulang. Ukuran terkompresi ini juga berbeda dari angka pada docker images, karena kolom SIZE dihitung setelah layer didekompresi di host, komputer tempat Docker berjalan.
Trade-off ukuran, kompatibilitas, dan alat diagnosis#
Ukuran bukan satu-satunya pertimbangan, sehingga tabel berikut merangkum keseimbangan ketiga varian resmi beserta distroless.
| Varian | Ukuran | Kompatibilitas | Alat diagnosis | Permukaan keamanan |
|---|---|---|---|---|
python:3.12 | paling besar | lengkap, semua paket tersedia | shell, apt, dan utilitas Debian penuh | paling banyak paket yang perlu dijaga |
python:3.12-slim | kecil | glibc, wheel ekstensi C terpasang langsung | shell dan apt masih ada | sedikit paket, mudah diinventaris |
python:3.12-alpine | paling kecil | musl, wheel glibc tidak terpakai | shell ada, alatnya minim | minim paket, tetapi berbeda pustaka C |
| distroless | kecil | bergantung pada penerbit image | tanpa shell dan tanpa manajer paket | paling sempit |
Kompatibilitas menjadi pertimbangan yang paling sering menentukan. Pustaka Python pihak ketiga yang mengandung ekstensi C biasanya didistribusikan sebagai wheel, paket biner siap pasang, dan wheel untuk Linux dibangun di atas glibc. Pada varian slim, wheel semacam itu terpasang tanpa kompilasi, sedangkan pada alpine, pustaka musl membuat wheel glibc tidak terpakai, sehingga kode C harus dikompilasi sendiri saat build, proses pembangunan image, atau dependensinya diambil dari paket Alpine. Untuk dependensi murni Python, perbedaan itu tidak terasa sama sekali.
Alat diagnosis menjadi pertimbangan kedua. Container, instans yang berjalan di atas image, pada varian distroless tidak disertai shell sama sekali, sehingga docker exec dengan shell tidak dapat dipakai saat error terjadi. Diagnosisnya dikerjakan dari luar container, misalnya melalui log dan docker inspect, atau dengan tahap debug terpisah. Varian slim dan alpine masih menyediakan shell, meskipun alat-alat di dalamnya minim.
Nama kode Debian#
Tag varian berbasis Debian dapat menunjuk nama kode rilis Debian. Bookworm adalah nama kode Debian 12, sedangkan trixie adalah nama kode Debian 13, keduanya diambil dari karakter film Toy Story sebagaimana konvensi penamaan Debian. Tag python:3.12-slim-bookworm mengunci rilisnya secara eksplisit, sedangkan tag tanpa akhiran nama kode, misalnya python:3.12-slim, mengikuti rilis yang menjadi dasar penerbitan image resmi saat ini. Perpindahan nama kode pada tag tanpa akhiran jarang terjadi, tetapi akibatnya besar, karena isi pustaka dan nomor versi paket dapat berubah sekaligus. Penguncian ini membuat hasil build tetap dapat direproduksi, dan perpindahan rilis menjadi keputusan yang disengaja alih-alih efek samping pembaruan.
Rekomendasi praktis#
Untuk aplikasi Python pada umumnya, varian slim menjadi pilihan default yang seimbang, karena ukurannya kecil, wheel ekstensi C terpasang tanpa kompilasi, dan shell masih tersedia saat diagnosis diperlukan. Varian alpine dipilih apabila ukuran benar-benar kritis dan seluruh dependensinya murni Python atau tersedia sebagai paket Alpine. Image distroless dipilih untuk produksi yang sudah matang karena permukaan serangannya paling sempit, dengan biaya penyiapan tahap build yang lebih teliti, misalnya melalui pola dua tahap pada topik Build Multi-Stage. Varian penuh python:3.12 tidak pernah keliru secara fungsional, tetapi ukurannya menjadikannya layak sebagai tahap build, bukan sebagai image produksi.
Rekomendasi itu juga berlaku sebagai urutan diagnosis, yaitu image yang terlalu besar jarang perlu diganti dasarnya lebih dahulu. Penyumbang terbesarnya biasanya layer aplikasi, bukan dasarnya. Perpindahan varian baru dipertimbangkan setelah penyumbang lainnya dirapikan.
Kesalahan umum#
- Memilih alpine lalu terkejut karena build menjadi lambat. Wheel glibc tidak terpakai di musl, sehingga ekstensi C dikompilasi saat build. Perbaikannya, periksa ketersediaan dependensi untuk musl lebih dahulu, atau kembali ke slim.
- Menganggap container distroless rusak karena
docker execdengan shell gagal. Shell memang tidak disertakan, dan perilaku itu disengaja. Perbaikannya, diagnosis dikerjakan dari luar container atau dengan tahap debug terpisah. - Memakai varian penuh hanya karena satu paket kecil tidak ada di slim. Seluruh paket Debian ikut terbawa demi satu kebutuhan. Perbaikannya, pasang paket yang dibutuhkan lewat
apt-getpada varian slim dengan pembersihan dalam satuRUN.
Ringkasan#
- Varian slim menjadi default aplikasi Python, karena berbasis glibc sehingga wheel ekstensi C terpasang tanpa kompilasi dan ukurannya jauh di bawah varian penuh.
- Varian alpine paling kecil karena memakai musl, sehingga hanya cocok untuk dependensi murni Python atau yang tersedia sebagai paket Alpine.
- Distroless paling sempit permukaan serangannya tetapi tidak memuat shell, sehingga diagnosis dilakukan dari luar container.
- Tag dengan nama kode Debian, misalnya bookworm, mengunci rilis dasar agar tidak berpindah mengikuti rilis terbaru.
Referensi#
- Base images — Docker Docs — Menguraikan peran image dasar dan pertimbangan memilihnya.
- Building best practices — Docker Docs — Menyarankan image dasar yang kecil dan dependensi seminimal mungkin.