Distribusi Image

Distribusi Image

Bitnesia Sep 12, 2026 10 EN

Setelah image berhasil di-push ke registry, baik ke Docker Hub maupun private registry sendiri, pekerjaan Sysadmin/DevOps Engineer belum selesai. Image itu masih perlu mengalir dari lingkungan development ke staging lalu production dengan cara yang bisa dilacak, tanpa risiko tag yang membingungkan atau image yang tiba-tiba berbeda isi meski nama tag-nya sama. Di sisi lain, tim yang punya banyak server atau cluster sering kali butuh cara menarik image lebih cepat tanpa membebani registry sumber berulang-ulang, sekaligus memastikan image yang beredar tidak menyimpan vulnerability yang membahayakan sistem production. Bab ini membahas strategi penamaan tag yang konsisten, pola promosi image antar lingkungan, mirror registry untuk efisiensi distribusi, dan pemindaian kerentanan sebagai bagian dari alur distribusi image yang aman.

21.1 Strategi Tagging

Tag adalah satu-satunya penanda yang membedakan versi image satu dengan yang lain dalam satu repository. Strategi tagging yang buruk membuat tim kesulitan melacak versi mana yang sedang berjalan di production, atau lebih parah, membuat deployment mengambil image yang salah tanpa disadari. Bagian ini membahas pola tagging yang umum dipakai di lapangan beserta jebakan yang perlu dihindari.

21.1.1 Masalah Tag latest

Tag latest bukan penanda otomatis untuk "versi paling baru" seperti namanya. Tag ini cuma nama tag biasa yang secara default ditempelkan Docker kalau tidak ada tag lain yang disebutkan saat docker build atau docker tag. Karena isinya bisa berubah kapan saja setiap kali ada push baru dengan tag yang sama, mengandalkan latest di production berarti tidak ada jaminan image yang ditarik hari ini sama dengan yang ditarik minggu lalu.

docker pull nginx:latest
docker pull nginx:latest

Dua perintah di atas terlihat identik, tapi bisa saja menghasilkan image dengan digest berbeda kalau maintainer nginx mem-push versi baru dengan tag latest di antara kedua pull tersebut. Di lapangan, kejadian seperti ini sering jadi penyebab bug "kerja di laptop saya, gagal di server" yang sebenarnya cuma soal versi image yang berbeda tanpa disadari. Tag latest masih boleh dipakai untuk development lokal atau contoh dokumentasi, tapi hindari merujuknya di file Dockerfile, docker-compose.yml, maupun manifest deployment yang dipakai di staging atau production.

21.1.2 Semantic Versioning

Pola tagging yang paling umum dipakai untuk image aplikasi adalah semantic versioning (semver), format MAJOR.MINOR.PATCH yang juga dipakai banyak base image resmi seperti node atau postgres. Angka MAJOR naik saat ada perubahan yang tidak kompatibel ke belakang, MINOR naik saat ada fitur baru yang tetap kompatibel, dan PATCH naik untuk perbaikan bug.

docker build -t registry.internal.perusahaan.com/payment-service:1.4.2 .
docker push registry.internal.perusahaan.com/payment-service:1.4.2

Selain tag versi lengkap, praktik umum lain adalah mem-push beberapa tag sekaligus untuk satu image yang sama, misalnya 1.4.2, 1.4, dan 1, sehingga konsumen image bisa memilih tingkat spesifisitas yang diinginkan: mengunci ke patch version tertentu untuk stabilitas penuh, atau mengikuti minor version terbaru untuk tetap mendapat bug fix otomatis.

docker tag payment-service:1.4.2 registry.internal.perusahaan.com/payment-service:1.4
docker tag payment-service:1.4.2 registry.internal.perusahaan.com/payment-service:1
docker push registry.internal.perusahaan.com/payment-service:1.4
docker push registry.internal.perusahaan.com/payment-service:1

Periksa apakah ketiga tag benar-benar merujuk image yang sama dengan membandingkan digest-nya lewat docker images --digests. Kolom DIGEST yang identik pada baris 1.4.2, 1.4, dan 1 menandakan ketiganya cuma label berbeda untuk satu image yang sama, bukan tiga image yang terpisah.

docker images --digests registry.internal.perusahaan.com/payment-service

21.1.3 Tagging Berbasis Git

Untuk pipeline CI/CD yang mem-build image di setiap commit, tagging berbasis semver saja sering tidak cukup granular karena tidak semua commit berujung pada rilis versi baru. Pola yang lazim dipakai Developer maupun Sysadmin/DevOps Engineer di sini adalah menandai image dengan git commit SHA (biasanya versi pendeknya), sehingga setiap build punya tag yang unik dan bisa langsung ditelusuri balik ke commit persis yang menghasilkannya.

GIT_SHA=$(git rev-parse --short HEAD)
docker build -t registry.internal.perusahaan.com/payment-service:$GIT_SHA .
docker push registry.internal.perusahaan.com/payment-service:$GIT_SHA

Tag berbasis SHA ini bersifat immutable secara konvensi, satu SHA tidak akan pernah dipakai ulang untuk isi image yang berbeda, sehingga aman dijadikan acuan di manifest deployment tanpa risiko isinya berubah diam-diam seperti masalah pada tag latest. Kombinasi yang sering dipakai di lapangan adalah tag SHA untuk keperluan tracing dan rollback presisi, ditambah tag semver untuk rilis resmi yang dikomunikasikan ke tim lain.

21.2 Image Promotion Pipeline

Setelah strategi tagging jelas, pertanyaan berikutnya adalah bagaimana satu image yang sama berpindah dari lingkungan development ke staging lalu production. Bagian ini membahas pola image promotion, yaitu memindahkan image yang sudah teruji antar lingkungan tanpa membangun ulang dari source code.

21.2.1 Build Sekali, Deploy Berkali-kali

Prinsip inti image promotion adalah build once, deploy many: image di-build satu kali oleh pipeline CI, lalu image persis yang sama, dengan digest yang identik, dipromosikan berjenjang ke setiap lingkungan setelah lolos pengujian di lingkungan sebelumnya. Ini berbeda dari pola yang keliru tapi cukup sering ditemui, yaitu mem-build ulang image terpisah untuk setiap lingkungan dengan harapan hasilnya identik. Build ulang membuka celah perbedaan, misalnya versi dependency yang berubah di antara dua waktu build karena tidak di-pin dengan ketat, sehingga image yang lolos tes di staging belum tentu benar-benar sama dengan yang berjalan di production.

Secara praktik, promosi berarti menandai ulang (re-tag) image yang sudah ada dengan tag baru yang menandakan lingkungan tujuannya, tanpa menjalankan docker build lagi.

docker pull registry.internal.perusahaan.com/payment-service:a1b2c3d
docker tag registry.internal.perusahaan.com/payment-service:a1b2c3d \
  registry.internal.perusahaan.com/payment-service:staging
docker push registry.internal.perusahaan.com/payment-service:staging

Setelah image dengan tag staging ini lolos pengujian, tag production ditempelkan ke digest yang sama persis, bukan hasil build baru.

docker tag registry.internal.perusahaan.com/payment-service:a1b2c3d \
  registry.internal.perusahaan.com/payment-service:production
docker push registry.internal.perusahaan.com/payment-service:production

21.2.2 Verifikasi Digest, Bukan Hanya Tag

Karena tag pada dasarnya cuma label yang bisa ditimpa, memverifikasi promosi image cuma dengan membandingkan nama tag tidak cukup meyakinkan. Cara yang lebih tepercaya adalah membandingkan digest, nilai hash SHA-256 dari manifest image yang berubah setiap kali isinya berubah, untuk memastikan image yang berjalan di production benar-benar identik dengan yang sudah lolos pengujian di staging.

docker inspect --format='{{index .RepoDigests 0}}' payment-service:staging
docker inspect --format='{{index .RepoDigests 0}}' payment-service:production

Banyak platform orchestration seperti Kubernetes juga mendukung referensi image langsung lewat digest (image@sha256:...), bukan cuma lewat nama dan tag, sehingga deployment production bisa dikunci ke satu digest spesifik yang sudah diverifikasi, alih-alih bergantung pada tag yang secara teknis masih bisa ditimpa isinya di registry.

21.2.3 Automated Promotion di Pipeline CI/CD

Di lapangan, proses re-tag dan push untuk promosi ini jarang dilakukan manual, melainkan jadi salah satu stage di pipeline CI/CD yang berjalan otomatis setelah stage pengujian sebelumnya lolos. Pola umumnya: stage build menghasilkan image dengan tag SHA, stage test menjalankan pengujian terhadap image tersebut, dan stage deploy mem-promosikan image yang sama ke lingkungan tujuan hanya kalau seluruh stage sebelumnya sukses. Promosi ke production dalam pola ini idealnya butuh approval gate tambahan, baik berupa persetujuan manual dari Sysadmin/DevOps Engineer yang bertanggung jawab, atau kondisi otomatis seperti hasil pemindaian kerentanan yang bersih dari temuan berisiko tinggi.

21.3 Mirror Registry

Semakin banyak server atau node cluster yang menarik image dari registry yang sama, semakin besar juga beban jaringan dan risiko terkena rate limit pull, terutama untuk image publik dari Docker Hub yang membatasi jumlah pull anonim maupun akun gratis dalam periode waktu tertentu. Mirror registry menjawab masalah ini dengan menyimpan salinan image lebih dekat ke node yang menariknya.

21.3.1 Registry Mirror sebagai Pull-Through Cache

Distribution mendukung mode pull-through cache, yaitu registry yang berperan sebagai mirror dari registry lain (biasanya Docker Hub): saat image diminta pertama kali, mirror ini mengambilnya dari registry asal lalu menyimpan salinannya secara lokal, dan permintaan berikutnya untuk image yang sama langsung dilayani dari cache tanpa perlu menghubungi registry asal lagi. Mode ini diaktifkan lewat bagian proxy di config.yml.

version: 0.1

storage:
  filesystem:
    rootdirectory: /var/lib/registry

http:
  addr: :5000

proxy:
  remoteurl: https://registry-1.docker.io
docker run -d -p 5000:5000 --restart=always --name registry-mirror \
  -v /mnt/mirror-data:/var/lib/registry \
  -v "$(pwd)"/config.yml:/etc/distribution/config.yml \
  registry:3

Registry yang dikonfigurasi dengan proxy.remoteurl ini bersifat read-only untuk keperluan pull, jadi tidak menerima push image baru secara langsung; fungsinya murni sebagai lapisan cache di depan registry asal.

21.3.2 Mengarahkan Docker Engine ke Mirror

Supaya seluruh perintah docker pull di sebuah mesin otomatis diarahkan lewat mirror tanpa perlu mengubah nama image satu per satu, Docker Engine bisa dikonfigurasi lewat opsi registry-mirrors di daemon.json.

{
  "registry-mirrors": ["https://registry-mirror.internal.perusahaan.com"]
}
sudo systemctl restart docker

Setelah konfigurasi ini aktif, perintah seperti docker pull nginx:1.27 tetap ditulis merujuk Docker Hub seperti biasa, tapi Docker Engine otomatis mencoba menariknya lewat mirror terlebih dulu sebelum jatuh kembali ke registry asal kalau mirror tidak bisa dijangkau. Pola ini banyak dipakai Sysadmin/DevOps Engineer yang mengoperasikan cluster dengan puluhan hingga ratusan node, karena node-node tersebut cukup menarik image populer sekali saja lewat mirror, lalu node lainnya mendapat manfaat cache tanpa membebani Docker Hub berulang kali dan tanpa cepat kena rate limit.

21.3.3 Verifikasi Mirror Berfungsi

Pastikan konfigurasi mirror sudah terbaca oleh Docker Engine lewat docker info, yang menampilkan daftar registry mirror aktif di bagian Registry Mirrors.

docker info --format '{{.RegistryConfig.Mirrors}}'

Kalau mirror sudah aktif tapi pull tetap terasa lambat, periksa log container mirror registry untuk memastikan proses proxy ke registry asal berjalan tanpa error, dan cek koneksi jaringan antara node dan mirror. Mirror yang tidak bisa dijangkau tidak membuat pull gagal total selama Docker Engine masih bisa jatuh kembali ke registry asal, tapi manfaat cache-nya otomatis hilang untuk sesi pull tersebut.

21.4 Pemindaian dan Kerentanan

Image yang lolos dari proses build tidak otomatis berarti aman. Base image yang dipakai bisa saja membawa package sistem dengan vulnerability yang sudah diketahui publik, dan dependency aplikasi yang di-install di dalamnya pun bisa punya celah keamanan yang baru terungkap belakangan. Bagian ini membahas pemindaian kerentanan sebagai langkah wajib sebelum image beredar lebih jauh ke staging maupun production.

21.4.1 Kenapa Pemindaian Perlu Jadi Bagian dari Pipeline

Attacker yang menemukan container dengan vulnerability yang belum ditambal berpotensi memakainya sebagai titik masuk, entah untuk mengeksekusi kode berbahaya di dalam container, mengeksfiltrasi data, atau dalam kasus terburuk melakukan container escape ke host. Karena vulnerability baru terus ditemukan pada package yang sudah ada, pemindaian bukan aktivitas sekali jalan yang cukup dilakukan saat image pertama kali dibuat, melainkan proses berulang yang idealnya berjalan otomatis setiap kali image baru di-build maupun secara berkala terhadap image yang sudah beredar di registry.

21.4.2 Memindai dengan Docker Scout

Docker Scout adalah tool pemindaian kerentanan bawaan yang terintegrasi langsung dengan Docker CLI dan Docker Hub, memakai basis data Common Vulnerabilities and Exposures (CVE) untuk mencocokkan package yang ditemukan di dalam layer image. Jalankan pemindaian cepat lewat subcommand docker scout quickview untuk melihat ringkasan jumlah vulnerability berdasarkan tingkat keparahannya.

docker scout quickview payment-service:1.4.2

Docker Scout sudah terpasang otomatis di Docker Desktop, tapi di server Linux yang cuma menjalankan Docker Engine tanpa Docker Desktop, plugin CLI-nya kadang perlu dipasang manual terlebih dulu. Kalau perintah docker scout merespons dengan pesan docker: 'scout' is not a docker command, itu tandanya plugin belum tersedia di instalasi tersebut; pasang lewat paket docker-scout-plugin yang disediakan repository resmi Docker untuk distribusi masing-masing, lalu ulangi perintahnya.

Untuk melihat daftar CVE secara detail lengkap dengan package yang terdampak dan versi yang sudah memperbaikinya, pakai subcommand cves.

docker scout cves payment-service:1.4.2

Docker Scout mengelompokkan temuan berdasarkan tingkat keparahan mengikuti standar Common Vulnerability Scoring System (CVSS): critical, high, medium, dan low. Sysadmin/DevOps Engineer biasanya menetapkan kebijakan bahwa image dengan temuan critical tidak boleh dipromosikan ke production sebelum ditambal, sementara temuan low atau medium bisa dijadwalkan perbaikannya tanpa menghentikan proses rilis.

21.4.3 Memindai dengan Trivy

Trivy adalah tool pemindaian kerentanan open source dari Aqua Security yang juga banyak dipakai karena bisa berjalan independen dari Docker Hub, mendukung pemindaian image, filesystem, maupun repository Git dalam satu tool yang sama. Trivy tersedia sebagai image container resmi, sehingga bisa langsung dipakai memindai image lain tanpa instalasi terpisah di host.

docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
  aquasec/trivy image payment-service:1.4.2

Perintah di atas mem-mount docker.sock supaya Trivy yang berjalan di dalam container bisa mengakses image yang tersimpan di Docker Engine host. Untuk kebutuhan pipeline CI/CD yang harus menghentikan proses build kalau ditemukan vulnerability tingkat tertentu, Trivy menyediakan flag --exit-code dan --severity yang membuatnya keluar dengan kode error non-nol kalau ditemukan kecocokan.

docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
  aquasec/trivy image --exit-code 1 --severity CRITICAL,HIGH payment-service:1.4.2

Pola ini memungkinkan pipeline CI/CD otomatis menggagalkan build begitu Trivy menemukan vulnerability CRITICAL atau HIGH, sehingga image dengan risiko tinggi tidak sempat lolos ke tahap push maupun promosi berikutnya.

21.4.4 Mengurangi Permukaan Serangan

Hasil pemindaian kerentanan akan jauh lebih bersih kalau permukaan serangan image ditekan sejak proses build, bukan cuma ditambal belakangan setelah temuan muncul. Beberapa langkah yang terbukti efektif di lapangan: memilih base image minimal seperti varian alpine atau distroless yang membawa jauh lebih sedikit package sistem dibanding base image penuh, rutin melakukan rebuild image secara berkala meski source code aplikasi tidak berubah supaya package sistem di dalamnya ikut ter-update ke versi yang sudah menambal vulnerability terbaru, serta menghapus tool build dan dependency development dari image final lewat pola multi-stage build. Kombinasi langkah-langkah ini tidak menghilangkan kebutuhan pemindaian rutin, tapi secara signifikan mengurangi jumlah temuan yang perlu ditangani setiap kali pemindaian dijalankan.