Docker Compose — DevOps

Apa itu Docker Compose? Docker Compose memungkinkan kita mendefinisikan dan menjalankan multi-container application menggunakan satu file YAML. Sangat berguna…

Docker Compose menjalankan beberapa container sekaligus dari satu file YAML. Tiap container disebut service, dan satu perintah, docker compose up, menyalakan semuanya dengan pengaturan yang sama setiap kali. Bayangin partitur orkestra: semua pemain, alat musiknya, dan siapa masuk setelah siapa ditulis di satu kertas, lalu dirigen memberi satu aba-aba. Tapi pemain biola yang sudah duduk belum tentu sudah selesai menyetem. Ingat bagian ini, karena di situ bug paling sering di Compose.

🧪 Tebakan cepat: service app punya depends_on: - db. Apakah Compose menunggu Postgres siap menerima koneksi sebelum menyalakan app? Tebak dulu, jawabannya ada di bagian "depends_on belum berarti siap".

Dari tiga docker run jadi satu file

catatan-api butuh tiga container: app Node-nya, Postgres untuk menyimpan catatan, dan Redis untuk cache daftar catatan. Dengan docker run, kamu harus membuat network, volume, lalu tiga perintah panjang, dengan urutan yang benar, setiap kali. Dengan Compose, semuanya ditulis sekali di docker-compose.yml (nama compose.yaml juga diterima) di folder project:

services:
  app:
    build: .
    env_file: .env
    ports:
      - "3000:3000"
    depends_on:
      - db
      - redis
  db:
    image: postgres:16
    environment:
      POSTGRES_USER: catatan
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - db-data:/var/lib/postgresql/data
  redis:
    image: redis:7-alpine

volumes:
  db-data:

Perintah sehari-hari

docker compose up -d          # build kalau perlu, buat network, lalu nyalakan semua di background
docker compose ps -a          # status semua container, termasuk yang sudah keluar
docker compose logs -f app    # ikuti log service app
docker compose up -d --build  # build ulang image app setelah kodenya berubah
docker compose down           # hentikan dan hapus container serta network
docker compose down -v        # sama, ditambah hapus volume: data database ikut hilang

depends_on belum berarti siap

Saat nyala, catatan-api langsung menyambung ke database untuk menjalankan migration, dan kalau gagal, dia keluar dengan exit code 1. Ini yang terjadi di up pertama, persis seperti di Lab:

Detik db app
0,0 container start, Postgres mulai menyiapkan database baru menunggu
0,7 masih menyiapkan container start (depends_on terpenuhi)
1,0 belum mendengarkan port 5432 menyambung, ditolak, exit 1
5,2 siap menerima koneksi sudah mati
app-1  | Gagal konek ke database: connect ECONNREFUSED 172.18.0.2:5432

Jadi jawabannya: gak. depends_on biasa cuma menunggu container db start, bukan Postgres di dalamnya siap. Itu jawaban tebakannya. Dan karena ini balapan waktu, kadang lolos (database-nya kebetulan sudah ada dan cepat siap), kadang gagal, yang bikin bug ini licin.

Obatnya: beri db sebuah healthcheck, perintah yang dijalankan Docker berulang kali untuk mengecek apakah service sehat, lalu suruh app menunggu status sehat itu:

  app:
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
  db:
    healthcheck:
      test: ["CMD", "pg_isready", "-h", "localhost", "-U", "catatan"]
      interval: 2s
      timeout: 3s
      retries: 15

Membaca daftar service

Latihan lesson ini memakai format yang disederhanakan: tiap service ditulis sebagai beberapa baris kunci: nilai, dan antar service dipisah satu baris kosong:

service: app
image: node:20
port: 3000

service: db
image: postgres:16
port: 5432

Nama service ada di baris yang diawali service: . Potong teksnya per baris dengan split("\n"), ambil baris yang startsWith("service: "), lalu buang awalan itu: hasilnya ["app", "db"], sesuai urutan di file.

⚠️ Jebakan yang sering ketemu

TL;DR: Docker Compose menulis semua service (app, db, redis) di docker-compose.yml dan menyalakannya dengan satu perintah. docker compose up -d jalan di background, ps -a melihat semua container termasuk yang keluar, logs -f app membaca log, up -d --build membangun ulang image, down menghapus container dan network, down -v juga menghapus volume beserta datanya. Nama service jadi nama host (db:5432). depends_on biasa cuma menunggu container start; supaya app menunggu database benar-benar siap, beri db healthcheck (pg_isready) dan tulis condition: service_healthy di depends_on app.

Yang akan kamu pelajari