Jika memungkinkan, saya selalu menggabungkan perintah yang membuat file dengan perintah yang menghapus file yang sama menjadi satu RUN
baris. Ini karena setiap RUN
baris menambahkan lapisan pada gambar, hasilnya secara harfiah perubahan sistem file yang dapat Anda lihat docker diff
pada wadah sementara yang dibuatnya. Jika Anda menghapus file yang dibuat di lapisan yang berbeda, yang dilakukan oleh sistem file gabungan adalah mendaftarkan perubahan sistem file di lapisan baru, file tersebut masih ada di lapisan sebelumnya dan dikirimkan melalui jaringan dan disimpan dalam disk. Jadi jika Anda mengunduh kode sumber, mengekstraknya, mengompilasinya menjadi biner, dan kemudian menghapus file tgz dan sumber pada akhirnya, Anda benar-benar ingin semua ini dilakukan dalam satu lapisan untuk mengurangi ukuran gambar.
Selanjutnya, saya pribadi membagi lapisan berdasarkan potensi mereka untuk digunakan kembali dalam gambar lain dan penggunaan caching yang diharapkan. Jika saya memiliki 4 gambar, semua dengan gambar dasar yang sama (misalnya debian), saya dapat menarik kumpulan utilitas umum ke sebagian besar gambar tersebut ke dalam perintah jalankan pertama sehingga gambar lain mendapat manfaat dari caching.
Urutan di Dockerfile penting ketika melihat penggunaan kembali cache gambar. Saya melihat setiap komponen yang akan memperbarui sangat jarang, mungkin hanya ketika gambar dasar diperbarui dan menempatkan mereka di Dockerfile. Menjelang akhir Dockerfile, saya menyertakan perintah yang akan berjalan cepat dan dapat sering berubah, misalnya menambahkan pengguna dengan host spesifik UID atau membuat folder dan mengubah izin. Jika wadah menyertakan kode yang ditafsirkan (misalnya JavaScript) yang sedang dikembangkan secara aktif, yang akan ditambahkan selambat mungkin sehingga pembangunan kembali hanya menjalankan perubahan tunggal itu.
Di masing-masing kelompok perubahan ini, saya melakukan konsolidasi sebaik mungkin untuk meminimalkan lapisan. Jadi jika ada 4 folder kode sumber yang berbeda, mereka ditempatkan di dalam satu folder sehingga dapat ditambahkan dengan satu perintah. Setiap paket yang diinstal dari sesuatu seperti apt-get digabung ke dalam RUN tunggal jika mungkin untuk meminimalkan jumlah overhead paket manajer (memperbarui dan membersihkan).
Pembaruan untuk bangunan multi-tahap:
Saya kurang khawatir tentang mengurangi ukuran gambar pada tahap non-final dari bangunan multi-tahap. Ketika tahap-tahap ini tidak ditandai dan dikirim ke node lain, Anda dapat memaksimalkan kemungkinan penggunaan kembali cache dengan memisahkan setiap perintah ke RUN
baris yang terpisah .
Namun, ini bukan solusi sempurna untuk menekan lapisan karena semua yang Anda salin di antara tahapan adalah file, dan bukan seluruh meta-data gambar seperti pengaturan variabel lingkungan, titik masuk, dan perintah. Dan ketika Anda menginstal paket dalam distribusi linux, perpustakaan dan dependensi lainnya dapat tersebar di seluruh sistem file, membuat salinan semua dependensi menjadi sulit.
Karena itu, saya menggunakan multi-stage builds sebagai pengganti untuk membangun binari pada server CI / CD, sehingga server CI / CD saya hanya perlu menjalankan tooling docker build
, dan tidak memiliki jdk, nodejs, go, dan alat kompilasi lain yang diinstal.