Kodeloka
  1. Kodeloka
  2. Kelas Docker
  3. Materi

Compose · Modul 13 dari 21

Compose Modern - Watch, Profile & Depends On

Alur pengembangan dengan sinkronisasi berkas otomatis, profil lingkungan, health check sebagai syarat startup, dan berkas compose berlapis.

Compose Watch — Hot Reload Tanpa Bind Mount

Cara lama memakai bind mount seluruh direktori, yang menimbulkan masalah: node_modules di host bentrok dengan yang di kontainer, kinerja berkas di macOS dan Windows sangat lambat, dan izin berkas sering kacau.

services:
  web:
    build: .
    ports: ["3000:3000"]
    develop:
      watch:
        # Salin berkas ke kontainer tanpa restart
        - action: sync
          path: ./src
          target: /app/src
          ignore: [node_modules/]

        # Bangun ulang image bila dependensi berubah
        - action: rebuild
          path: ./package.json

        # Salin lalu restart proses
        - action: sync+restart
          path: ./config
          target: /app/config
docker compose watch
📌 Tiga aksi dan kapan memakainya
  • sync — untuk berkas yang ditangani hot-reload aplikasi (React, nodemon, uvicorn --reload).
  • sync+restart — untuk berkas konfigurasi yang hanya dibaca saat proses menyala.
  • rebuild — untuk manifest dependensi seperti package.json, go.mod, requirements.txt.

Profil — Satu Berkas untuk Banyak Skenario

services:
  api:
    build: .
    # tanpa profiles -- selalu ikut berjalan

  db:
    image: postgres:17-alpine

  # Hanya menyala bila diminta
  pgadmin:
    image: dpage/pgadmin4
    profiles: ["alat"]

  mailhog:
    image: mailhog/mailhog
    profiles: ["alat", "dev"]

  worker:
    build: .
    command: celery -A tugas worker
    profiles: ["pekerja"]
docker compose up                          # hanya api & db
docker compose --profile alat up           # + pgadmin & mailhog
docker compose --profile "*" up            # semuanya

depends_on dengan Kondisi — Menghentikan Balapan Startup

🚫 depends_on biasa hanya menunggu kontainer MENYALA
Ia tidak menunggu layanan di dalamnya siap melayani. Kontainer PostgreSQL menyala dalam sepersekian detik, tetapi butuh beberapa detik lagi sebelum menerima koneksi. Aplikasi Anda akan gagal terhubung lalu mati — inilah penyebab masalah "kadang jalan, kadang tidak" yang sangat sering ditemui.
services:
  db:
    image: postgres:17-alpine
    environment:
      POSTGRES_PASSWORD: rahasia
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 3s
      retries: 5
      start_period: 10s

  redis:
    image: redis:8-alpine
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      retries: 5

  migrasi:
    build: .
    command: alembic upgrade head
    depends_on:
      db: { condition: service_healthy }

  api:
    build: .
    depends_on:
      db:      { condition: service_healthy }
      redis:   { condition: service_healthy }
      migrasi: { condition: service_completed_successfully }
KondisiMenunggu sampai
service_startedKontainer menyala (perilaku bawaan)
service_healthyHealth check melaporkan sehat
service_completed_successfullyKontainer selesai dengan kode keluar 0

Berkas Berlapis untuk Dev dan Produksi

# compose.yaml — dasar bersama
services:
  api:
    image: registry.contoh.com/app:${TAG:-latest}
    environment:
      DATABASE_URL: postgresql://postgres:rahasia@db:5432/app
    depends_on:
      db: { condition: service_healthy }

  db:
    image: postgres:17-alpine
    volumes: [data_db:/var/lib/postgresql/data]

volumes:
  data_db:
# compose.override.yaml — otomatis dipakai saat pengembangan
services:
  api:
    build: .
    ports: ["8000:8000"]
    environment:
      DEBUG: "true"
    develop:
      watch:
        - action: sync
          path: ./app
          target: /app/app
# compose.prod.yaml — dipanggil eksplisit
services:
  api:
    restart: unless-stopped
    deploy:
      replicas: 3
      resources:
        limits: { memory: 512M }
    logging:
      driver: json-file
      options: { max-size: "10m", max-file: "3" }
docker compose up                                    # dasar + override otomatis
docker compose -f compose.yaml -f compose.prod.yaml up -d

Kesalahan Umum

⚠️ Rotasi log sering terlupakan
Tanpa opsi logging, berkas log kontainer tumbuh tanpa batas sampai memenuhi disk server. Ini penyebab pemadaman yang membingungkan karena gejalanya muncul berbulan-bulan setelah deploy. Selalu setel max-size dan max-file.
# ❌ Rahasia langsung di berkas yang masuk git
environment:
  DB_PASSWORD: rahasia123

# ✅ Dari berkas .env yang diabaikan git
environment:
  DB_PASSWORD: ${DB_PASSWORD:?wajib diisi}

# ✅ Atau memakai secret Compose
secrets:
  db_password:
    file: ./rahasia/db_password.txt

services:
  api:
    secrets: [db_password]
    environment:
      DB_PASSWORD_FILE: /run/secrets/db_password
# Perintah yang berguna
docker compose config              # tampilkan hasil gabungan akhir
docker compose ps --format json
docker compose logs -f --tail=100 api
docker compose exec api sh
docker compose down -v             # ⚠️ -v juga MENGHAPUS volume beserta datanya