Banyak orang belajar Docker dengan cara yang sama.

Mereka menghafal command. docker run, docker ps, docker exec. Semua terasa masuk akal, sampai akhirnya harus menjalankan aplikasi nyata.

Di titik itu, semuanya mulai terasa berantakan.

Harus menjalankan beberapa container. Harus menghubungkan aplikasi dengan database. Harus mengatur port. Kadang harus mengingat urutan command yang benar.

Masalahnya bukan di Docker. Masalahnya adalah pendekatannya.

Docker pada dasarnya bukan tentang menjalankan satu container. Docker lebih berguna ketika kita menjalankan beberapa service sebagai satu sistem.

Di situlah Docker Compose menjadi masuk akal.


Dari banyak command menjadi satu file

Alih-alih menjalankan container satu per satu, Docker Compose memungkinkan kita mendefinisikan semuanya dalam satu file: docker-compose.yml.

File ini berisi:

  • service apa saja yang dijalankan
  • image yang digunakan
  • port yang dibuka
  • environment variable
  • volume (jika ada)

Contoh paling sederhana:

version: '3'

services:
  web:
    image: nginx
    ports:
      - "8080:80"

Jalankan dengan satu perintah:

docker compose up -d

Buka browser ke localhost:8080, dan aplikasi sudah berjalan.


Memahami isi file Docker Compose (yang sering bikin bingung)

Banyak pemula bisa copy-paste file di atas, tapi belum benar-benar paham artinya.

Mari kita breakdown:

version: '3'

Menentukan versi format Docker Compose.

  • Biasanya cukup pakai '3'
  • Tidak terlalu penting untuk pemula, tapi tetap diperlukan untuk kompatibilitas

services

Tempat mendefinisikan semua container yang akan dijalankan.

services:
  web:

Artinya:

  • Kita membuat satu service bernama web
  • Nama ini akan digunakan untuk referensi internal antar container

image: nginx

image: nginx

Artinya:

  • Container ini menggunakan image nginx dari Docker Hub
  • Jika belum ada di lokal, Docker akan otomatis download

ports

ports:
  - "8080:80"

Formatnya:

host_port:container_port

Artinya:

  • Port 8080 di server → diteruskan ke port 80 di dalam container

Jika tidak ada ini:
→ aplikasi tidak bisa diakses dari browser


Kenapa ini lebih masuk akal

Dengan pendekatan ini, kamu tidak lagi berpikir dalam bentuk command.

Kamu mulai berpikir dalam bentuk sistem.

  • Apa saja service yang dibutuhkan?
  • Bagaimana mereka saling terhubung?
  • Apa konfigurasi yang diperlukan?

Semua jawaban itu ada dalam satu file yang bisa dibaca, disimpan, dan dijalankan ulang kapan saja.


Contoh yang lebih realistis (App + Database)

Sebagian besar aplikasi tidak hanya terdiri dari satu service.

Biasanya ada aplikasi dan database.

version: '3'

services:
  app:
    image: node:18
    ports:
      - "3000:3000"
    volumes:
      - ./app:/app
    working_dir: /app
    command: npm start

  db:
    image: postgres
    environment:
      POSTGRES_PASSWORD: example

Breakdown bagian penting (ini yang sering bikin error)

app: dan db:

Nama service.

  • app = aplikasi kamu
  • db = database
  • Nama ini juga menjadi hostname internal (misalnya app bisa akses db dengan db:5432)

image: node:18

Menggunakan image Node.js versi 18.

  • Ini adalah environment tempat aplikasi berjalan
  • Tidak perlu install Node manual di server

ports

- "3000:3000"

Artinya:

  • Port 3000 di server → port 3000 di container

volumes

- ./app:/app

Artinya:

  • Folder ./app di server → di-mount ke /app di container

Fungsi:

  • Code di lokal bisa langsung dipakai di container
  • Tidak perlu rebuild image setiap perubahan

working_dir

working_dir: /app

Artinya:

  • Semua command dijalankan dari folder /app

command

command: npm start

Artinya:

  • Saat container jalan, otomatis menjalankan npm start

environment

environment:
  POSTGRES_PASSWORD: example

Artinya:

  • Set environment variable di dalam container
  • Digunakan untuk konfigurasi aplikasi atau database

Command yang benar-benar sering dipakai

Menjalankan semua service:

docker compose up -d

Menghentikan:

docker compose down

Melihat log:

docker compose logs -f

Melihat service:

docker compose ps

Pola berpikir yang lebih penting dari command

Saat menggunakan Docker Compose, kamu tidak lagi fokus pada “command apa yang harus dijalankan”.

Kamu fokus pada:

  • service apa saja yang dibutuhkan
  • bagaimana mereka terhubung
  • bagaimana konfigurasi mereka

Ini perbedaan besar.


Kesalahan yang sering terjadi

Port tidak di-mapping, akhirnya aplikasi tidak bisa diakses

Volume tidak dipasang akhirnya perubahan tidak terlihat

Environment salah, akhirnya database gagal koneksi

Nama service salah, akhirnya container tidak bisa saling komunikasi

Sebagian besar masalah ada di konfigurasi, bukan di Docker.


Docker sering terlihat kompleks karena dipelajari sebagai kumpulan command.

Padahal kekuatannya justru muncul ketika kita mulai melihatnya sebagai cara untuk menjalankan sistem dengan konsisten.

Docker Compose menyederhanakan itu.

Ia mengubah banyak langkah manual menjadi satu definisi yang jelas.

Dan setelah kamu memahami isi file-nya, Docker tidak lagi terasa seperti sesuatu yang harus dihafal, tetapi sesuatu yang bisa dipahami.