DevOps & Keamanan

Docker untuk Pemula: Memahami Image, Container, Dockerfile, dan Docker Compose dengan Contoh Aplikasi Web

Pengantar Docker untuk programmer pemula: apa bedanya image dan container, perintah dasar yang paling sering dipakai, contoh Dockerfile aplikasi Node.js, menjalankan aplikasi dan database dengan Docker Compose, menyimpan data dengan volume, serta kesalahan yang sering terjadi.

"Di laptop saya jalan, kok di server error?" Kalimat ini sering muncul karena versi runtime, library, atau setelan sistem di dua komputer berbeda. Docker menyelesaikan masalah itu dengan membungkus aplikasi beserta seluruh kebutuhannya ke dalam satu paket yang bisa dijalankan sama persis di mana saja. Artikel ini membahas dasar Docker dengan contoh aplikasi web sederhana dan database. Gambaran besarnya dalam alur kerja tim ada di DevOps untuk tim kecil.

Image dan container

Dua istilah ini paling sering membingungkan pemula. Analogi yang mudah: image seperti resep atau cetakan, sedangkan container adalah kue yang dibuat dari cetakan itu.

IstilahPenjelasanContoh
ImagePaket read-only berisi sistem dasar, runtime, library, dan kode aplikasinode:20-alpine, postgres:16
ContainerProses yang sedang berjalan dari sebuah image, terisolasi dari sistem lainAplikasi web Anda yang sedang melayani di port 3000
DockerfileFile teks berisi langkah-langkah membuat imagePilih base image, salin kode, install dependensi
RegistryTempat menyimpan dan berbagi imageDocker Hub, GitLab Container Registry
VolumePenyimpanan data yang tetap ada walau container dihapusFolder data database

Satu image bisa dijalankan menjadi banyak container sekaligus. Container juga berbeda dengan mesin virtual: container memakai kernel sistem operasi host sehingga jauh lebih ringan dan cepat dinyalakan.

Perintah dasar yang paling sering dipakai

# unduh image dan jalankan container nginx di port 8080
docker run -d --name web-uji -p 8080:80 nginx:alpine

# lihat container yang sedang berjalan
docker ps

# lihat log dan masuk ke dalam container
docker logs web-uji
docker exec -it web-uji sh

# hentikan lalu hapus container
docker stop web-uji
docker rm web-uji

# daftar image di komputer
docker images

Opsi -p 8080:80 berarti port 8080 di komputer Anda diteruskan ke port 80 di dalam container. Setelah perintah pertama, buka http://localhost:8080 dan halaman nginx akan muncul tanpa perlu menginstal nginx di laptop.

Membuat image sendiri dengan Dockerfile

Misalkan ada aplikasi Node.js sederhana dengan package.json dan server.js yang mendengarkan port 3000. Dockerfile-nya:

FROM node:20-alpine
WORKDIR /app

# salin daftar dependensi dulu agar cache layer terpakai
COPY package*.json ./
RUN npm ci --omit=dev

# baru salin kode aplikasi
COPY . .

ENV NODE_ENV=production
EXPOSE 3000
USER node
CMD ["node", "server.js"]

Beberapa hal yang perlu diperhatikan:

  • Urutan langkah memengaruhi kecepatan build. Docker menyimpan hasil setiap langkah sebagai layer. Karena package.json jarang berubah, menyalinnya lebih dulu membuat npm ci tidak diulang setiap kali kode diubah.
  • Base image alpine berukuran kecil, cocok untuk aplikasi sederhana.
  • USER node menjalankan aplikasi sebagai pengguna biasa, bukan root, sehingga lebih aman.

Buat juga file .dockerignore agar folder yang tidak perlu tidak ikut tersalin:

node_modules
.git
.env
*.log

Lalu build dan jalankan:

docker build -t jadwal-poli:1.0 .
docker run -d --name jadwal-poli -p 3000:3000 jadwal-poli:1.0

Aplikasi dan database dengan Docker Compose

Aplikasi nyata hampir selalu butuh lebih dari satu layanan, misalnya aplikasi web dan database PostgreSQL. Menjalankan banyak docker run dengan opsi panjang mudah salah. Docker Compose menuliskan semuanya dalam satu file compose.yaml:

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgres://klinik:rahasia-lokal@db:5432/klinik
    depends_on:
      - db
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: klinik
      POSTGRES_PASSWORD: rahasia-lokal
      POSTGRES_DB: klinik
    volumes:
      - dbdata:/var/lib/postgresql/data

volumes:
  dbdata:

Jalankan semuanya dengan docker compose up -d, lihat log dengan docker compose logs -f app, dan hentikan dengan docker compose down. Perhatikan bahwa aplikasi memanggil database dengan nama host db, yaitu nama layanan di file Compose, bukan localhost. Contoh struktur tabel untuk aplikasi seperti ini dibahas di desain database aplikasi klinik.

Volume: jangan sampai data hilang

Container dirancang sekali pakai. Semua yang ditulis di dalam container hilang saat container dihapus. Karena itu data yang harus bertahan, seperti isi database atau file unggahan, wajib disimpan di volume, seperti dbdata pada contoh di atas.

  • docker compose down menghapus container tetapi volume tetap ada.
  • docker compose down -v ikut menghapus volume beserta seluruh datanya. Jangan jalankan perintah ini di server produksi kecuali memang bermaksud mengosongkan data.
  • Volume bukan backup. Tetap buat backup database terjadwal ke lokasi lain; lihat RPO, RTO, dan rencana pemulihan bencana.

Kesalahan yang sering terjadi

  • Menyimpan password atau API key di Dockerfile atau image. Siapa pun yang punya image bisa membacanya. Simpan rahasia di environment variable atau fitur secrets, dan jangan commit file .env ke Git. Contoh password di atas hanya untuk lingkungan lokal.
  • Memakai tag latest di produksi. Isi latest bisa berubah sewaktu-waktu. Pakai versi yang jelas, misalnya postgres:16-alpine atau jadwal-poli:1.0.
  • Membuka port database ke internet. Pada contoh Compose, layanan db sengaja tidak punya bagian ports sehingga hanya bisa diakses oleh aplikasi di jaringan internal Compose.
  • Image terlalu besar karena ikut menyalin node_modules, folder build, atau file log. Gunakan .dockerignore.
  • Menganggap localhost di dalam container sama dengan laptop. Di dalam container, localhost adalah container itu sendiri.

Langkah belajar berikutnya

  1. Bungkus satu proyek kecil Anda dengan Dockerfile dan jalankan di laptop.
  2. Tambahkan database dengan Docker Compose dan pastikan datanya tetap ada setelah docker compose down lalu up lagi.
  3. Bangun image otomatis di pipeline CI setiap ada perubahan di branch utama, lalu simpan di registry. Alur branch-nya dibahas di alur kerja Git untuk tim kecil.
  4. Deploy image yang sama ke server staging, uji, lalu ke produksi.

Pertanyaan yang sering diajukan

Apakah Docker bisa dipakai di Windows? Bisa, melalui Docker Desktop yang memakai WSL 2, atau dengan menginstal Docker Engine langsung di distribusi Linux dalam WSL 2.

Apakah semua aplikasi harus memakai Docker? Tidak. Untuk situs statis atau aplikasi yang sudah berjalan di layanan terkelola, Docker mungkin tidak perlu. Docker paling terasa manfaatnya saat aplikasi punya beberapa layanan, dikerjakan beberapa orang, atau harus dipasang di banyak server.

Apa bedanya Docker dan Kubernetes? Docker membuat dan menjalankan container. Kubernetes mengatur banyak container di banyak server: penjadwalan, skala otomatis, dan pemulihan saat ada yang mati. Untuk tim kecil, Docker Compose di satu atau dua server biasanya sudah cukup sebelum mempertimbangkan Kubernetes.