Bayangkan tab Tags milik budi/katalog-web tiga bulan dari sekarang: hampir empat puluh tag tercantum — 2.0, 2.1, latest, beberapa 8f3c21e-style penanda commit, mungkin satu-dua nama eksperimen yang lupa dibersihkan. Pertanyaan yang sama akan ditanyakan tim saat insiden jam tiga pagi: image mana yang sedang berjalan di produksi? Selama section ini kita menulis tag seadanya — cukup untuk latihan, tetapi untuk rilis sungguhan tag adalah kontrak antara proses build dan proses deploy, dan kontrak yang kabur melahirkan insiden klasik “kemarin masih jalan, hari ini gagal padahal tidak ada yang mengubah apa pun”. Chapter penutup section ini merapikan urusan tersebut: membandingkan skema penamaan, menetapkan kebijakan mutasi yang disiplin, mengunci deployment lewat digest, dan menjalankan satu alur rilis lengkap dari awal sampai akhir.
Dua Sifat yang Menentukan Nasib Deployment #
Dua sifat tag dari chapter-chapter sebelumnya menjadi alasan strategi ini harus diperlakukan serius. Pertama, tag bersifat mutable — push ulang ke tag yang sama akan menimpa isinya, sehingga budi/katalog-web:2.1 hari ini dan minggu lalu bisa jadi dua image berbeda tanpa satu penanda pun. Kedua, latest hanyalah tag biasa yang tidak pernah bergeser sendiri — dua server yang sama-sama “memakai latest” bisa menjalankan versi berbeda tergantung kapan terakhir kali keduanya menarik image. Deployment yang sehat menuntut jawaban tegas atas satu pertanyaan: dari sekian banyak cara memberi nama, mana yang membuat hasil bisa direproduksi dan diaudit?
Peta Strategi Tagging #
Lima skema berikut adalah pilihan utama di lapangan, masing-masing dengan kekuatan dan kelemahan yang jujur:
| Strategi | Contoh tag | Kelebihan | Kekurangan |
|---|---|---|---|
latest saja | latest | paling sederhana; selalu satu nama | tidak reproducible; rollback mustahil |
| Semver | 2.2.0 | makna versi jelas dan dibaca semua orang sama | tetap mutable bila kebijakan longgar |
| Git SHA | 8f3c21e | identik dengan commit sumber; satu SHA satu build | tidak menyiratkan urutan rilis |
| Build number CI | 123 | naik monoton; unik per build | tidak berarti apa pun di luar sistem CI |
| Kombinasi | 2.2.0 + SHA + latest | reproducible sekaligus nyaman manusia | menuntut otomatisasi yang disiplin |
Bergantung penuh pada latest hanya cocok untuk eksperimen pribadi yang hidup beberapa hari di satu mesin. Begitu ada dua lingkungan atau dua orang yang menarik image pada waktu berbeda, kita kehilangan kemampuan menjawab pertanyaan operasional paling dasar — versi apa yang berjalan di sana — dan latest yang lama sudah tertimpa sehingga tidak bisa dipanggil kembali untuk rollback.
Semver memberi bahasa versi yang disepakati manusia: MAJOR.MINOR.PATCH — major naik untuk perubahan yang merusak kompatibilitas, minor untuk fitur baru yang kompatibel, patch untuk perbaikan bug. Praktik penyertainya adalah tag mengapung di level yang lebih kasar: 2.2 mengikuti patch terbaru dari 2.2.x. Git SHA menautkan image langsung ke kode sumbernya — SHA berbeda pasti commit berbeda — dan hampir tidak pernah digeser ulang, sehingga image lawas tetap bisa dipanggil untuk audit. Build number menomori build secara berurutan dari CI; “lebih baru” mudah dibaca, tetapi untuk mengetahui isi 123 kita harus membuka log build. Kombinasi memakai ketiganya sekaligus pada rilis yang sama — semver sebagai identitas resmi, SHA sebagai penelusuran ke kode, latest sebagai penunjuk bergerak — dan kemampuan multi-tag yang kita bangun pada Chapter Tagging Image memang dibuat untuk pola ini.
Kebijakan Mutasi Tag #
Skema apa pun yang dipilih, kebijakan mutasi yang menentukan apakah skema itu bisa dipercaya. Empat aturan berikut adalah kontrak minimum yang sehat:
- Tag rilis tidak pernah digeser. Setelah
2.2.0diterbitkan, isi tag itu terkunci selamanya; ada perbaikan, rilis baru bernama2.2.1. Menimpa tag rilis yang sudah dipakai orang adalah pembatalan kepercayaan terhadap seluruh sistem. latesthanya mengikuti rilis stabil terbaru. Satu-satunya tag yang boleh bergeser adalahlatest— dan pergeserannya harus terjadi sebagai bagian dari proses rilis, bukan dari build eksperimen tengah malam.- Tag tanggal untuk snapshot berkala. Penanda seperti
2026.10pada build mingguan membuat umur image mudah diaudit: cukup membaca nama untuk tahu kapan image itu dilahirkan. - Tag mengapung hanya untuk development.
2.2boleh bergerak mengikuti rilis terbaru di cabangnya, tetapi deployment produksi tidak boleh bergantung padanya — bahayanya sama denganlatest, hanya lebih halus.
Mengunci Deployment dengan Digest #
Kebijakan di atas mengurus manusia; digest mengurus mesin. Bagi manifest produksi, bentuk paling aman menyebut image adalah digest, bukan tag — materi Chapter Image Digest yang kini menemukan medan perangnya. Di server produksi, baris image pada compose.prod.yaml kita berubah bentuk dari interpolasi tag menjadi kunci permanen:
services:
web:
image: budi/katalog-web@sha256:c4f2e6a91b7d30f5a8c2e9b4d1f7a3c6e0b8d5f2a9c1e4b7d0f3a6c9e2b5d8f1Mari kita telaah bentuknya: sintaks nama@sha256:... menimpa peran tag sepenuhnya — deployment selalu menarik bit yang persis sama sekalipun ada tag yang digeser orang di registry. Upgrade menjadi keputusan eksplisit: ganti digest di berkas, commit, deploy; rollback tinggal kembali ke digest lama yang masih tersimpan di riwayat berkas. Variabel IMAGE_TAG tetap berguna untuk staging yang memang ingin mengikuti rilis terbaru, tetapi produksi berhak menuntut kepastian mutlak. Kubernetes memakai bentuk yang sama persis pada manifest Pod-nya:
containers:
- name: web
image: budi/katalog-web@sha256:c4f2e6a91b7d30f5a8c2e9b4d1f7a3c6e0b8d5f2a9c1e4b7d0f3a6c9e2b5d8f1Satu baris yang sama berlaku di dua dunia — konsekuensi langsung dari standarisasi yang kita bahas di Chapter Pengantar Container Registry — dan seluruh pembahasan Kubernetes menunggu di Section Orchestration dan Ekosistem.
Alur Rilis 2.2.0 dari Awal sampai Akhir #
Saatnya merangkai semuanya. Skenarionya: fitur terakhir untuk rilis 2.2.0 sudah merge ke branch utama pada commit 8f3c21e, dan Budi bertindak sebagai release manager. Langkah pertama: membangun image dengan seluruh identitasnya sekaligus — nomor semver, tag mengapung minor, SHA commit, dan latest:
$ docker build \
-t budi/katalog-web:2.2.0 \
-t budi/katalog-web:2.2 \
-t budi/katalog-web:8f3c21e \
-t budi/katalog-web:latest \
.Empat alias lahir dari satu build, menunjuk satu IMAGE ID yang sama. Langkah kedua: menerbitkan setiap tag secara eksplisit ke registry:
$ docker push budi/katalog-web:2.2.0Output yang Dihasilkan:
The push refers to repository [docker.io/budi/katalog-web]
7a3e9c1f5d24: Layer already exists
c48e2b6d90af: Layer already exists
5f1d8a3c7e29: Layer already exists
9b2e6fa8d41c: Layer already exists
8a5c2e9b41f7: Pushed
2.2.0: digest: sha256:c4f2e6a91b7d30f5a8c2e9b4d1f7a3c6e0b8d5f2a9c1e4b7d0f3a6c9e2b5d8f1 size: 1570Empat layer dasar dijawab Layer already exists — rilis sebelumnya sudah membayarnya — dan hanya layer kode aplikasi yang dikirim. Tiga push berikutnya memperlihatkan hal yang sama dengan satu perbedaan penting: baris digest pada keempat push bernilai identik, karena keempat tag menunjuk manifest yang sama.
$ docker push budi/katalog-web:2.2
$ docker push budi/katalog-web:8f3c21e
$ docker push budi/katalog-web:latestLangkah ketiga: membaca digest resmi rilis untuk dikunci di manifest produksi:
$ docker image inspect --format '{{index .RepoDigests 0}}' budi/katalog-web:2.2.0Output yang Dihasilkan:
budi/katalog-web@sha256:c4f2e6a91b7d30f5a8c2e9b4d1f7a3c6e0b8d5f2a9c1e4b7d0f3a6c9e2b5d8f1Field RepoDigests terisi setelah push dan menyimpan pasangan nama repository dengan digest yang tercatat di registry — nilai inilah yang ditempelkan ke kunci image pada compose.yaml di server produksi, lalu dideploy. Selesai? Belum — seminggu kemudian bug ditemukan di 2.2.0. Kebijakan kita melarang menimpa tag rilis, jadi perbaikan dirilis sebagai 2.2.1 dari commit baru 4b9d07c: build dengan empat alias baru, push empat tag, perbarui digest di manifest produksi, deploy. Tag 2.2 dan latest bergeser mengikuti 2.2.1 sesuai aturan kedua dan keempat, sementara 2.2.0 tetap tercatat di registry untuk siapa pun yang perlu mengaudit kejadian minggu lalu — rollback ke sana pun tinggal menulis ulang satu digest.
Memilih Strategi Sesuai Ukuran Tim #
Terakhir, tidak ada strategi tunggal untuk semua tim — tabel berikut memetakan pilihan yang layak seiring kompleksitas naik:
| Situasi tim | Strategi yang layak |
|---|---|
| Latihan pribadi, satu mesin | latest saja — dan bersiap bermigrasi begitu mesin kedua muncul |
| Proyek kecil, satu-dua developer | semver + latest |
| Tim dengan staging dan produksi | kombinasi semver + SHA + latest |
| Organisasi dengan kewajiban audit | kombinasi + digest pin di manifest + tag tanggal untuk snapshot |
Pola yang sama kita saksikan pada official images yang kita pakai sepanjang Course ini: nginx:1.29.4 untuk mereka yang menuntut kepastian, nginx:1.29 untuk yang ingin mengikuti patch, nginx:latest untuk yang sekadar mencoba — satu repository melayani semua tingkat kedisiplinan.
Section Registry dan Distribusi kini tuntas: image kita punya nama yang benar dan alamat yang sehat — Docker Hub untuk distribusi publik, repository privat dan mirror untuk wilayah kendali sendiri, digest untuk kepastian mutlak, serta disiplin versi yang membuat setiap deployment bisa direproduksi dan diaudit. Image katalog-web beredar di laptop Siti, di workstation Budi, dan kelak di pipeline CI. Pertanyaan berikutnya sudah mengetuk dari luar pintu: sekarang setelah banyak container berjalan di banyak mesin, bagaimana kita mengawasi apa yang terjadi di dalamnya — log yang keluar, kesehatan yang memudar, resource yang membengkak? Log, inspect, stats, dan events adalah perangkat diagnosisnya, dan seluruhnya dibahas pada Section Observability dan Troubleshooting.
Referensi #
- Dockerfile Best Practices — panduan resmi pola penandaan versi image.
- docker image tag — CLI Reference — aturan referensi untuk pola multi-tag.
- Compose file reference — kunci image
— bentuk
imagedengan tag maupun digest pada service.