Kembali ke Artikel

Perbedaan Docker Image dan Container + Praktik Pertama

Solusi IT

Perbedaan Docker image dan container sebenarnya sederhana. Image adalah paket read-only berisi filesystem, aplikasi, dan konfigurasi yang dibutuhkan untuk menjalankan sebuah program. Container adalah proses yang berjalan dari image itu. Image sifatnya statis, seperti file yang diam di disk. Container sifatnya hidup, punya proses, punya memori, dan bisa dihentikan atau dihapus tanpa menyentuh image aslinya.

Artikel ini bagian kedua dari seri Belajar Docker dari Nol. Setelah paham konsepnya, kita langsung praktik: menjalankan Nginx di container, melihat prosesnya, membukanya di browser, lalu membedah kenapa ada container yang langsung mati begitu dijalankan.

Prasyarat: Docker Sudah Terpasang

Kamu butuh Docker Engine yang sudah jalan di komputermu. Kalau belum, ikuti dulu bagian pertama seri ini: Apa Itu Docker dan Cara Install Docker di Ubuntu & Windows. Semua contoh di sini saya jalankan di Ubuntu 24.04 dengan Docker Engine 27, tapi perintahnya sama persis di Windows dengan Docker Desktop.

Cek dulu instalasimu:

docker --version

Output yang diharapkan kurang lebih seperti ini (angka minor boleh beda):

Docker version 27.5.1, build 9f9e405

Analogi Paling Gampang: Image Itu Cetakan, Container Itu Hasil Cetakannya

Bayangkan cetakan kue. Cetakan itu cuma satu, bentuknya tetap, dan tidak berubah sedikit pun setiap kali dipakai. Dari satu cetakan yang sama, kamu bisa membuat sepuluh kue. Tiap kue berdiri sendiri. Kue pertama boleh kamu makan, kue kedua boleh gosong, cetakannya tetap utuh.

Docker persis seperti itu. Image adalah cetakannya. Container adalah kuenya. Dari satu image nginx, kamu bisa menjalankan lima container Nginx sekaligus, masing-masing dengan nama, port, dan isi memori sendiri. Menghapus salah satu container tidak berpengaruh apa pun ke image, dan tidak berpengaruh ke container lain.

Kalau dirangkum dalam tabel:

Aspek Image Container
Sifat Read-only, statis Hidup, punya proses yang berjalan
Analogi Cetakan kue Kue hasil cetakan
Jumlah Satu image Bisa jadi banyak container
Disimpan di Disk lokal, hasil pull dari registry Dibuat saat docker run, di atas image
Kalau dihapus Container baru tidak bisa dibuat darinya Image tetap aman, container lain tetap jalan

Satu detail teknis yang penting: saat container dibuat, Docker tidak menyalin seluruh isi image. Docker hanya menambahkan satu lapisan tulis (writable layer) tipis di atas image. Semua perubahan file di dalam container terjadi di lapisan ini. Itulah kenapa membuat container itu cepat sekali, hitungan detik, bukan menit seperti menyalakan virtual machine.

Arsitektur Docker: Client, Daemon, dan Registry

Sebelum praktik, kenali dulu tiga aktor utama supaya kamu paham apa yang sebenarnya terjadi saat mengetik perintah.

  • Docker client, yaitu perintah docker yang kamu ketik di terminal. Dia tidak menjalankan container sendiri, dia cuma mengirim permintaan.
  • Docker daemon (dockerd), proses yang jalan di background. Dialah yang benar-benar bekerja: membangun image, membuat container, mengatur network dan storage.
  • Registry, gudang image di internet atau server internal. Yang paling populer adalah Docker Hub. Dari sinilah image nginx, mysql, dan lainnya diunduh.

Saat kamu mengetik docker run nginx, urutan kejadiannya seperti ini:

  1. Client mengirim permintaan ke daemon lewat socket.
  2. Daemon mengecek apakah image nginx sudah ada di disk lokal.
  3. Kalau belum ada, daemon melakukan pull dari registry (Docker Hub) dan menyimpannya di lokal.
  4. Daemon membuat container baru dari image itu, menambahkan writable layer di atasnya.
  5. Daemon menjalankan proses utama container, dalam kasus Nginx yaitu web servernya.

Pemahaman alur ini kepakai terus sampai level produksi. Di tim Arrazy, alur yang sama persis kami pakai saat men-deploy backend Go dan Laravel milik klien ke server, hanya saja registry-nya kadang privat, bukan Docker Hub.

Praktik: Menjalankan Nginx di Container Pertamamu

Cukup teori. Jalankan perintah ini:

docker run -d -p 8080:80 --name webku nginx:1.27

Penjelasan singkat flag-nya. -d membuat container jalan di background. -p 8080:80 menyambungkan port 8080 di komputermu ke port 80 di dalam container. --name webku memberi nama supaya gampang dirujuk. Detail lengkap soal port mapping dan mode detach dibahas khusus di bagian 4 seri ini, sekarang cukup pakai dulu.

Karena ini pertama kali, Docker akan pull image dulu. Outputnya kurang lebih:

Unable to find image 'nginx:1.27' locally
1.27: Pulling from library/nginx
a480a496ba95: Pull complete
f3ace1b8ce45: Pull complete
11d6fdd0e8a7: Pull complete
Digest: sha256:...
Status: Downloaded newer image for nginx:1.27
3f9c1d2e8b7a...

Baris terakhir yang berupa deretan huruf dan angka itu adalah ID container barumu. Sekarang lihat container yang sedang jalan:

docker ps

Output yang diharapkan:

CONTAINER ID   IMAGE        COMMAND                  CREATED          STATUS          PORTS                  NAMES
3f9c1d2e8b7a   nginx:1.27   "/docker-entrypoint.…"   10 seconds ago   Up 9 seconds    0.0.0.0:8080->80/tcp   webku

Perhatikan kolom STATUS bertuliskan Up. Artinya container hidup dan proses Nginx sedang berjalan di dalamnya. Sekarang buka browser dan akses http://localhost:8080. Kamu akan melihat halaman default dengan tulisan Welcome to nginx! di bagian atasnya. Kalau lebih suka lewat terminal:

curl http://localhost:8080

Responsnya HTML yang diawali <title>Welcome to nginx!</title>. Web server pertamamu di Docker sudah jalan.

Membuktikan Satu Image Bisa Jadi Banyak Container

Sekarang buktikan analogi cetakan tadi. Jalankan container kedua dari image yang sama, dengan nama dan port berbeda:

docker run -d -p 8081:80 --name webku2 nginx:1.27

Kali ini tidak ada proses pull karena image sudah ada di lokal, jadi container langsung jalan dalam waktu kurang dari satu detik. Cek dengan docker ps, sekarang ada dua container, webku dan webku2, dua-duanya dari image nginx:1.27 yang sama. Buka http://localhost:8081, hasilnya halaman Nginx juga. Satu cetakan, dua kue.

Siklus Hidup Container: Created, Running, Exited

Container punya beberapa status utama yang perlu kamu hafal:

  • Created: container sudah dibuat dari image tapi prosesnya belum dijalankan. Terjadi kalau kamu pakai docker create tanpa docker start.
  • Running: proses utama di dalam container sedang berjalan. Inilah yang muncul di docker ps.
  • Exited: proses utamanya sudah berhenti, entah karena selesai, error, atau dihentikan manual.

Coba hentikan container kedua:

docker stop webku2

Lalu jalankan docker ps lagi. Container webku2 hilang dari daftar. Nah, di sinilah banyak pemula bingung: containernya ke mana?

Jawabannya, container itu tidak hilang. Dia masih ada di disk dengan status Exited, hanya saja docker ps secara default cuma menampilkan container yang running. Untuk melihat semuanya, tambahkan flag -a:

docker ps -a

Output:

CONTAINER ID   IMAGE        COMMAND                  CREATED         STATUS                     PORTS                  NAMES
7b2e4a1c9d03   nginx:1.27   "/docker-entrypoint.…"   5 minutes ago   Exited (0) 30 seconds ago                         webku2
3f9c1d2e8b7a   nginx:1.27   "/docker-entrypoint.…"   8 minutes ago   Up 8 minutes               0.0.0.0:8080->80/tcp   webku

Container Exited bisa dihidupkan lagi dengan docker start webku2, lengkap dengan isi writable layer-nya yang masih utuh. Kalau memang sudah tidak dibutuhkan, hapus permanen dengan:

docker stop webku2
docker rm webku2

Ingat, docker rm hanya menghapus container. Image nginx:1.27 tetap ada di disk dan bisa dipakai membuat container baru kapan saja. Menghapus image adalah perintah lain, yaitu docker rmi, dan hanya bisa dilakukan kalau tidak ada container yang masih memakainya.

Kenapa Container Langsung Exit? Kasus docker run ubuntu

Ini kebingungan paling klasik. Coba jalankan:

docker run -d --name coba-ubuntu ubuntu:24.04

Lalu cek docker ps. Kosong, tidak ada coba-ubuntu. Cek docker ps -a, ternyata statusnya Exited (0) padahal baru saja dijalankan. Kenapa Nginx bertahan hidup tapi Ubuntu langsung mati?

Aturannya satu: container hanya hidup selama proses utamanya hidup. Image nginx proses utamanya adalah web server yang memang dirancang berjalan terus menerus di foreground, menunggu request. Image ubuntu proses utamanya adalah bash. Karena container jalan di background tanpa terminal interaktif, bash tidak punya input apa pun, jadi dia langsung selesai. Bash selesai, container ikut exit. Ini bukan error, ini perilaku yang benar.

Kalau mau masuk ke dalam Ubuntu dan main-main di shell-nya, jalankan dengan mode interaktif:

docker run -it --name ubuntu-interaktif ubuntu:24.04 bash

Flag -it memberi container terminal interaktif, jadi bash tetap hidup dan kamu langsung berada di dalam container. Prompt-mu berubah jadi seperti root@a1b2c3d4e5f6:/#. Ketik exit untuk keluar, dan begitu bash berhenti, container pun berstatus Exited. Konsisten dengan aturannya.

Troubleshooting: Error yang Sering Dialami Pemula

Error: port is already allocated

docker: Error response from daemon: ... bind: address already in use

Penyebab: port 8080 di komputermu sudah dipakai, entah oleh container lain atau aplikasi lain. Solusi: pakai port host lain, misalnya -p 8082:80, atau cari siapa yang memakai port itu dengan docker ps lalu stop container yang bentrok.

Error: the container name is already in use

docker: Error response from daemon: Conflict. The container name "/webku" is already in use

Penyebab: nama container harus unik, dan container lama bernama sama masih ada meskipun statusnya Exited. Solusi: hapus dulu container lama dengan docker rm webku, atau pakai nama lain.

Error: Cannot connect to the Docker daemon

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

Penyebab: dockerd tidak jalan, atau user-mu belum punya izin mengakses socket Docker. Solusi di Ubuntu: jalankan sudo systemctl start docker. Kalau masalahnya izin, pastikan user sudah masuk grup docker seperti dibahas di bagian 1, lalu logout dan login lagi. Di Windows, pastikan aplikasi Docker Desktop sedang berjalan.

Container Nginx jalan tapi browser tidak bisa akses

Penyebab paling umum: lupa flag -p saat docker run, jadi port container tidak tersambung ke host. Cek kolom PORTS di docker ps. Kalau kosong, hapus container itu dan jalankan ulang dengan -p 8080:80. Port mapping tidak bisa ditambahkan ke container yang sudah terlanjur dibuat.

Rangkuman dan Lanjut ke Bagian 3

Hari ini kamu sudah memegang konsep paling fundamental di Docker. Image itu cetakan yang read-only, container itu instance hidup yang dibuat dari cetakan tersebut, dan satu image bisa melahirkan banyak container yang saling independen. Kamu juga sudah tahu alur kerja client, daemon, dan registry, plus aturan emas bahwa container hanya hidup selama proses utamanya hidup.

Pola kerja ini sama persis dengan yang dipakai di dunia kerja. Saat tim Arrazy membangun sistem aplikasi untuk klien, satu image backend yang sama bisa dijalankan sebagai container di laptop developer, di server staging, dan di server produksi tanpa ada cerita “di laptop saya jalan kok”.

Bagian berikutnya, “Perintah Dasar Docker yang Wajib Dikuasai Pemula”, akan membedah perintah harian seperti docker ps, docker images, docker rm, dan kawan-kawannya secara sistematis. Artikelnya terbit menyusul, pantau daftarnya di halaman Belajar Docker dari Nol.

Referensi

BACA JUGA

Artikel Lainnya di Kategori Docker

Ingin Membaca Artikel Lainnya?

Temukan lebih banyak insight dan tips tentang teknologi dan bisnis digital.

Lihat Semua Artikel