Dua kolom yang paling sering kita tatap pada docker images adalah REPOSITORY dan TAG — dua potongan kecil teks yang menentukan image mana yang diunduh dan dijalankan. Teks kecil itu ternyata punya anatomi: segmen registry, namespace, repository, dan tag yang dirangkai mengikuti aturan ketat. Salah membaca anatominya bisa berarti menarik image dari registry yang salah, menerima versi yang tidak diinginkan, atau bahkan menjalankan image milik orang lain yang sengaja dinamai mirip. Chapter ini membedah nama image sampai ke aturan deteksinya, lalu membedah tag sebagai penunjuk yang bisa bergeser, dan ditutup dengan peta varian image yang harus kita pilih dengan sadar.

Anatomi Nama Image #

Nama yang kita ketik sehari-hari seperti nginx sebenarnya adalah bentuk singkat. Bentuk lengkapnya muncul di baris terakhir setiap output docker pull pada Chapter Menarik Image: docker.io/library/nginx:latest. Pola umumnya adalah registry/namespace/repository:tag dengan tiga aturan pemendekan: registry boleh disingkat, namespace boleh disingkat, dan tag boleh disingkat — dan setiap singkatan memiliki nilai bawaannya sendiri. Tabel berikut membedah setiap segmen dari bentuk lengkap nginx:

SegmenNilai pada contohWajib ditulis?Peran
registrydocker.iotidak — bawaan Docker Hubserver registry tempat image disimpan
namespacelibrarytidak — bawaan image resmipemilik repositori: akun atau organisasi
repositorynginxyanama image itu sendiri
taglatesttidak — bawaan latestpenunjuk versi yang menempel pada repository

Aturan yang sama berlaku untuk registry lain. GitHub misalnya menyediakan ghcr.io untuk paket milik repositori dan organisasi, sementara perusahaan umumnya menjalankan registry privat dengan nama domain sendiri — topik yang kita dalami pada Section Registry dan Distribusi. Tiga contoh berikut memperlihatkan keragaman itu sekaligus cara Docker membacanya:

Referensiregistrynamespacerepositorytag
docker.io/library/nginx:latestdocker.iolibrarynginxlatest
ghcr.io/acme/api:v2.1.0ghcr.ioacmeapiv2.1.0
budi/aplikasi-webdocker.io (bawaan)budiaplikasi-weblatest (bawaan)

Perhatikan contoh ketiga: budi/aplikasi-web tidak menyebut registry dan tag sama sekali, sehingga Docker melengkapi keduanya dengan nilai bawaan — registry docker.io dan tag latest. Contoh kedua menunjukkan penamaan versi semantik v2.1.0 yang lazim pada image aplikasi internal: mayor, minor, dan patch dirangkai agar urutan rilisnya terbaca.

Aturan Deteksi Registry #

Bagaimana Docker tahu bahwa ghcr.io/acme/api memiliki registry sedangkan budi/aplikasi-web tidak? Jawabannya satu aturan sederhana: bila segmen pertama nama mengandung titik atau titik dua, segmen itu dibaca sebagai registry. Titik menandakan nama domain seperti ghcr.io atau registry.example.com; titik dua menandakan port seperti registry.example.com:5000. Segmen pertama tanpa keduanya — seperti budi — pasti namespace, dan nama pendek seperti nginx bahkan langsung dibaca sebagai repository resmi. Kesalahan klasiknya mudah ditebak: memberi nama image seperti aplikasi.web/v1 membuat Docker membaca aplikasi.web sebagai registry, sehingga pull gagal karena registry yang dicari tidak pernah ada.

Tag: Penunjuk yang Bisa Bergeser #

Di mata Docker, tag bukan bagian dari isi image — tag adalah penunjuk (pointer) yang menempel pada repository dan boleh dipindahkan penerbitnya kapan saja. Isi image sendiri immutable: sekali dibangun, byte-nya tidak berubah, dan identitas sejatinya adalah digest yang tercetak pada setiap output pull. Satu image bisa ditunjuk banyak tag sekaligus, seperti satu orang yang dipanggil banyak nama. Mari kita buktikan dua fakta itu di mesin latihan yang sudah menyimpan nginx:latest:

bash
$ docker pull nginx:1.29.4

Output yang Dihasilkan:

text
1.29.4: Pulling from library/nginx
Digest: sha256:348334896a6815a9c39de3ae8b7c3a37d64efbeac71edc6a2f83ee6e0f77a0d5
Status: Image is up to date for nginx:1.29.4
docker.io/library/nginx:1.29.4
bash
$ docker images nginx:1.29.4

Output yang Dihasilkan:

text
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
nginx        1.29.4    613f27b0341a   3 days ago   187MB

Mari kita telaah kedua output di atas:

  1. Status: Image is up to date — Docker menemukan bahwa tag 1.29.4 dan tag latest yang sudah dimiliki mesin menunjuk manifest dengan digest yang identik, sehingga tidak ada satu byte pun yang diunduh.
  2. Digest sha256:348334896a68... — sama persis dengan digest pada output docker pull nginx di awal Chapter Menarik Image: tag berbeda, image sama.
  3. IMAGE ID 613f27b0341a pada tabel — ID yang sama dengan baris nginx latest pada tabel docker images di Chapter Melihat Image Lokal: dua tag, satu image. Pada saat riset Course ini, tag 1.29, 1.29.4, dan latest sama-sama menunjuk image tersebut.

Karena tag hanya penunjuk, menghapus satu tag tidak serta-merta menghapus imagenya — selama masih ada penunjuk lain yang menempel, seluruh layer tetap tersimpan. Docker menyebut langkah penghapusan nama ini sebagai Untagged, dan konsekuensinya kita bedah pada Chapter Menghapus Image. Sifat mutable inilah sumber dua jebakan paling terkenal di ekosistem Docker, dan keduanya berpusat pada tag latest.

Dua Jebakan Tag latest #

Jebakan pertama: latest tidak menjanjikan versi termutakhir selamanya — ia hanya menunjuk versi yang paling baru pada saat penerbit memindahkannya. Hari ini tarikan nginx:latest memberi image berdigest sha256:348334896a68...; begitu nginx merilis versi baru dan menggeser tag tersebut, tarikan berikutnya memberi image lain tanpa pemberitahuan apa pun. Build yang kemarin berhasil bisa tiba-tiba berperilaku berbeda hari ini hanya karena tag bergeser.

Jebakan kedua bekerja ke arah sebaliknya: docker run nginx pada image yang sudah tersimpan lokal tidak mengecek registry sama sekali — daemon langsung memakai apa yang ada di penyimpanan lokal. Image latest yang kita tarik setahun lalu akan terus dipakai diam-diam, padahal di registry sudah ada versi baru yang berganti berkali-kali. Tanpa docker pull eksplisit, label latest pada mesin kita bisa saja berarti versi paling lawas di ruangan.

Spektrum Referensi: dari Mengambang sampai Terkunci #

Antara latest yang bebas bergerak dan digest yang terkunci mati, tersedia sebuah spektrum pilihan — dan memilih titik di spektrum itu adalah keputusan teknis, bukan selera. Tabel berikut merangkum spektrum tersebut untuk nginx beserta tingkat kepastiannya:

ReferensiApa yang terkunciSaat penerbit merilis versi baruCocok untuk
nginx:latesthampir tidak adatarikan berikutnya berpindah imageeksplorasi dan latihan
nginx:stablekanal rilis stabiltetap di kanal stabil, versi di dalamnya bergeserpengembangan sehari-hari
nginx:1.29rilis major.minortetap pada 1.29, versi patch di dalamnya naikstaging
nginx:1.29.4versi lengkaptetap menunjuk rilis 1.29.4produksi
nginx@sha256:348334896a68...isi image byte-per-bytetidak pernah bergeseraudit dan kebutuhan ketat

Bahkan tag versi lengkap seperti 1.29.4 secara teknis tetap bisa digeser penerbitnya — praktik buruk yang jarang dilakukan, tetapi tetap mungkin. Hanya digest yang menjamin immutability mutlak: digest dihitung dari manifest image, sehingga isi yang berbeda selalu menghasilkan digest yang berbeda pula. Karena itulah referensi digest menjadi standar pada berkas lock, pipeline CI, dan deklarasi infrastructure-as-code — praktiknya kita kerjakan pada Chapter Image Digest.

Varian Image: alpine, slim, dan bookworm #

Satu nama repository kerap menyembunyikan banyak varian image yang dibangun untuk kebutuhan berbeda — dan varian menentukan ukuran maupun perilaku image di dalamnya. Tag alpine menandakan basis Alpine Linux yang mungil; tag slim menandakan basis Debian yang dipangkas sampai tinggal yang penting; sedangkan bookworm adalah nama kode Debian 12 yang dicantumkan pada tag untuk menandai generasi basis secara eksplisit. Tabel berikut membandingkan varian yang paling sering dijumpai:

VarianContoh tagUkuran terpasangBasisKarakter
alpinenginx:1.29-alpine47.9MBAlpine Linuxpaling kecil; libc musl
standarnginx:latest187MBDebian bookwormpaling kompatibel; libc glibc
slimpython:3.12-slimsekitar 125MBDebian dipangkastitik tengah untuk image bahasa
kode basisnode:22-bookwormsekitar 1GBDebian bookworm penuhmenandai generasi basis secara eksplisit

Angka ukuran pada tabel adalah perkiraan saat riset Course ini dan akan bergeser mengikuti pembaruan penerbit masing-masing; angka 47.9MB dan 187MB adalah ukuran terpasang yang kita pakai konsisten sepanjang section ini. Perbedaan paling teknis namun paling sering menggigit ada di libc: varian Debian memakai glibc — pustaka C standar di hampir semua distribusi besar — sedangkan varian Alpine memakai musl yang jauh lebih ringan.

Binary yang dikompilasi menautkan glibc tidak akan berjalan di image alpine, dan kegagalannya sering menyesatkan: galat klasiknya exec /usr/local/bin/app: no such file or directory padahal berkasnya jelas ada — yang hilang justru dynamic linker glibc yang tidak tersedia di Alpine. Untuk image buatan sendiri yang berisi binary Go statis atau skrip Python murni, varian alpine biasanya aman dan menghemat besar; untuk binary pihak ketiga yang menautkan glibc, tetaplah memilih varian Debian. Kita akan kembali menghadapi pilihan ini ketika menyusun Dockerfile pada Section Dockerfile dan mengecilkan image pada Section Image Build dan Optimisasi.

Nama image kini kita baca utuh: registry, namespace, repository, dan tag beserta aturan singkat dan aturan deteksinya; tag kita perlakukan sebagai penunjuk yang bisa bergeser; dan varian kita pilih dengan sadar sesuai kebutuhan ukuran dan kompatibilitas. Satu bagian masih sengaja menggantung: digest — identitas yang menjanjikan image yang sama, di mesin mana pun, untuk selamanya. Chapter Image Digest mengajarkan cara membaca, membandingkan, dan mengunci image dengan sidik jari 64 karakter itu.

Referensi #