Best Practice #
Docker image adalah fondasi dari seluruh ekosistem container. Image yang buruk akan berdampak langsung pada keamanan, ukuran, kecepatan build, waktu startup, dan stabilitas di production. Sebaliknya, Docker image yang dirancang dengan baik akan membuat deployment lebih cepat, scaling lebih efisien, dan operasional lebih tenang.
Artikel ini membahas best practice Docker image secara menyeluruh, tidak terikat pada bahasa pemrograman tertentu, dan relevan untuk aplikasi modern (monolith, microservice, hingga serverless container).
Prinsip Dasar Docker Image yang Baik #
Sebelum masuk ke teknis, ada beberapa prinsip fundamental:
- Small is better – image kecil lebih cepat ditarik dan lebih aman
- Immutable – image tidak diubah setelah dibuild
- Single responsibility – satu image = satu tujuan utama
- Secure by default – minim permission, minim attack surface
- Reproducible – build harus konsisten di mana pun
Semua best practice di bawah berakar dari prinsip-prinsip ini.
Memilih Base Image dengan Bijak #
Gunakan Base Image Sekecil Mungkin #
Hindari base image besar kecuali benar-benar dibutuhkan.
Urutan preferensi umum:
scratchdistrolessalpinedebian-slimubuntu
Semakin ke bawah, semakin besar attack surface dan ukuran image.
Pahami Konsekuensi Alpine #
Alpine sangat populer, tetapi:
- Menggunakan
musl libc(bukanglibc) - Beberapa binary/library bisa bermasalah
- Debugging lebih sulit
Gunakan Alpine jika:
- Aplikasi statically linked
- Dependensi minimal
- Sudah teruji di production
Gunakan Multi-Stage Build #
Multi-stage build adalah best practice wajib.
Masalah Tanpa Multi-Stage #
- Image membawa compiler
- Image membawa source code
- Image membawa cache build
Solusi Multi-Stage #
Konsepnya:
- Stage pertama: build
- Stage terakhir: runtime saja
Hasilnya:
- Image jauh lebih kecil
- Lebih aman
- Lebih bersih
Multi-stage build juga memudahkan:
- Cross compilation
- Optimasi dependency
- Pemisahan concern build vs runtime
Jangan Jalankan Aplikasi sebagai Root #
Secara default, container berjalan sebagai root. Ini berbahaya.
Best Practice #
- Buat user non-root
- Jalankan aplikasi dengan user tersebut
Manfaat:
- Mengurangi dampak jika container compromise
- Lebih sesuai dengan security policy Kubernetes
- Mandatory di beberapa environment enterprise
Minimalkan Layer Docker Image #
Setiap instruksi RUN, COPY, dan ADD menambah layer.
Praktik yang Baik #
- Gabungkan perintah
RUN - Bersihkan cache dalam layer yang sama
Contoh konsep:
- Install dependency
- Hapus cache
- Semua dalam satu
RUN
Ini menjaga image:
- Lebih kecil
- Lebih rapi
- Lebih cepat ditransfer
Gunakan .dockerignore
#
Tanpa .dockerignore, Docker akan:
- Mengirim seluruh context ke daemon
- Memperlambat build
- Berpotensi membocorkan file sensitif
Wajib Dikecualikan #
.gitnode_modulesvendor.env- File log
- File build lokal
.dockerignore sama pentingnya dengan .gitignore.
Jangan Simpan Secret di Docker Image #
Kesalahan fatal yang sering terjadi:
- API key di Dockerfile
- Credential di ENV saat build
- File secret dicopy ke image
Best Practice #
Inject secret saat runtime
Gunakan:
- Environment variable
- Secret manager (Kubernetes, AWS, GCP)
Ingat: Docker image bersifat immutable dan mudah di-distribute.
Gunakan Tag Image dengan Benar #
Hindari latest
#
latest:
- Tidak deterministic
- Sulit rollback
- Membingungkan saat incident
Strategi Tag yang Baik #
- Semantic version (
1.2.3) - Git commit hash
- Build number
Contoh:
app:1.4.0app:1.4.0-rc.1app:git-a1b2c3
Optimasi Dependency #
Install Hanya yang Dibutuhkan #
- Jangan install tool debug di production image
- Pisahkan dependency build dan runtime
Audit Dependency #
- Hapus dependency yang tidak dipakai
- Hindari “install all” mindset
Dependency berlebih =
- Image besar
- Attack surface luas
- Update security lebih sering
Perhatikan Caching Docker Build #
Docker build cache bisa sangat membantu jika urutan Dockerfile benar.
Prinsip Umum #
- Instruksi yang jarang berubah di atas
- Source code di bawah
Ini akan:
- Mempercepat build
- Menghemat resource CI/CD
Tambahkan Metadata pada Image #
Gunakan label untuk dokumentasi:
- Maintainer
- Source repository
- Version
- Description
Manfaat:
- Observability
- Audit
- Traceability
Sangat membantu di environment besar.
Scan Vulnerability Docker Image #
Image kecil ≠ image aman.
Best Practice #
- Scan image secara rutin
- Integrasikan ke CI/CD
Yang perlu diperhatikan:
- CVE OS package
- CVE dependency aplikasi
Image yang aman adalah image yang terawat, bukan hanya kecil.
Jangan Jadikan Docker Image sebagai VM #
Anti-pattern yang sering muncul:
- Menjalankan banyak service dalam satu container
- Menggunakan supervisor
- Treat container seperti server tradisional
Ingat #
- Container ≠ VM
- Satu container = satu proses utama
Ini memudahkan:
- Scaling
- Monitoring
- Recovery
Best Practice untuk Production #
Ringkasan prinsip production-grade Docker image:
- Gunakan multi-stage build
- Base image sekecil mungkin
- Non-root user
- Tanpa secret di image
- Tag version dengan jelas
- Image immutable
- Scan vulnerability rutin
Jika sebuah image:
- Kecil
- Aman
- Mudah direproduksi
Maka operasional Anda akan jauh lebih stabil.
Penutup #
Docker image bukan sekadar artefak build, tetapi kontrak operasional antara developer, CI/CD, dan runtime environment. Investasi pada best practice Docker image akan membayar dirinya sendiri dalam bentuk:
- Deployment lebih cepat
- Incident lebih sedikit
- Security posture lebih kuat
- Biaya infra lebih efisien
Dockerfile yang baik adalah tanda tim engineering yang matang.