Docker Compose Tingkat Lanjut

Docker Compose Tingkat Lanjut

Bitnesia Sep 12, 2026 10 EN

Satu file compose.yaml saja sering tidak cukup begitu aplikasi bertumbuh. Developer butuh konfigurasi berbeda untuk development dan production, beberapa service kadang punya konfigurasi dasar yang mirip dan ingin dipakai ulang tanpa menyalin-nyalin, lalu Sysadmin/DevOps Engineer perlu jaminan bahwa urutan startup antar service benar-benar aman sebelum aplikasi dianggap siap melayani trafik. Bab ini melanjutkan pembahasan dari dasar-dasar Docker Compose dengan empat topik tingkat lanjut: menyusun override file untuk memisahkan konfigurasi per environment, memakai extends untuk komposisi konfigurasi antar service, mengontrol urutan startup dan shutdown lewat depends_on secara lebih mendalam, serta kumpulan perintah CLI docker compose yang paling sering dipakai sehari-hari.

18.1 Override Files

Override file memungkinkan kita menyimpan konfigurasi dasar yang sama di satu file, lalu menambahkan atau mengganti sebagian konfigurasi lewat file lain sesuai environment yang sedang dipakai, tanpa harus menduplikasi seluruh compose.yaml.

18.1.1 compose.override.yaml Otomatis

Compose secara otomatis membaca file bernama compose.override.yaml di direktori yang sama dengan compose.yaml setiap kali kita menjalankan docker compose up, tanpa perlu menyebutkannya lewat opsi apa pun. Pola ini cocok dipakai untuk menyimpan konfigurasi khusus development, seperti bind mount source code atau port tambahan untuk debugging, supaya compose.yaml utama tetap bersih dan siap dipakai di production.

# compose.yaml
services:
  app:
    image: myapp:latest
    ports:
      - "3000:3000"

  db:
    image: postgres:16-alpine
# compose.override.yaml
services:
  app:
    build: .
    volumes:
      - ./src:/app/src
    environment:
      DEBUG: "true"

  db:
    ports:
      - "5432:5432"

Saat kita menjalankan docker compose up di direktori yang berisi kedua file di atas, service app otomatis dibangun dari source lokal lewat build: . alih-alih menarik image: myapp:latest, sekaligus mendapat bind mount dan environment variable tambahan dari compose.override.yaml. Instruksi ports pada service db juga ditambahkan, sehingga port database yang semula tidak dibuka ke host jadi bisa diakses langsung saat development. Verifikasi hasil gabungan kedua file ini sebelum benar-benar menjalankan container lewat perintah berikut.

docker compose config

18.1.2 Menentukan Override Manual dengan -f

Untuk environment selain development, misalnya staging atau production, kita bisa memberi nama file override sendiri lalu memanggilnya secara eksplisit lewat opsi -f, karena Compose hanya membaca compose.override.yaml secara otomatis.

# compose.prod.yaml
services:
  app:
    image: myapp:latest
    restart: unless-stopped
    deploy:
      resources:
        limits:
          memory: 512M
docker compose -f compose.yaml -f compose.prod.yaml up -d

Compose menggabungkan file-file tersebut sesuai urutan penyebutannya di opsi -f, dengan file yang disebut belakangan menimpa atau menambah konfigurasi dari file sebelumnya. Menurut dokumentasi resmi Docker Compose, seluruh path relatif di dalam file-file yang digabung ini dihitung relatif terhadap file dasar, yaitu file pertama yang disebut lewat -f, bukan relatif terhadap lokasi file override itu sendiri. Kalau struktur project menyebar file Compose di beberapa subdirektori tim yang berbeda, path relatif di override file bisa salah resolusi kalau cara ini dipakai; untuk kasus semacam itu, elemen include jadi pilihan yang lebih aman karena setiap file yang di-include tetap memakai direktori proyeknya sendiri sebagai acuan path.

Di lapangan, Sysadmin/DevOps Engineer biasanya menyiapkan beberapa file override sekaligus, misalnya compose.staging.yaml dan compose.prod.yaml, lalu memilih kombinasi -f yang sesuai lewat script deployment atau pipeline CI/CD, supaya satu compose.yaml dasar bisa dipakai konsisten di semua environment tanpa duplikasi konfigurasi.

18.2 Extends dan Composition

Instruksi extends memungkinkan sebuah service mewarisi konfigurasi dari service lain yang didefinisikan di file yang sama maupun file terpisah, berguna saat beberapa service punya konfigurasi dasar yang identik namun butuh sedikit penyesuaian.

18.2.1 Mewarisi Konfigurasi dengan extends

Bayangkan sebuah aplikasi worker yang punya dua mode jalan: sebagai web server dan sebagai background worker, namun keduanya memakai image, environment, dan konfigurasi dasar yang sama. Kita bisa memisahkan konfigurasi bersama ini ke file terpisah agar tidak ditulis dua kali.

# common.yaml
services:
  app-base:
    build: .
    environment:
      CONFIG_FILE_PATH: /code/config
      API_KEY: xxxyyy
# compose.yaml
services:
  web:
    extends:
      file: common.yaml
      service: app-base
    command: /code/run_web
    ports:
      - "8080:8080"

  worker:
    extends:
      file: common.yaml
      service: app-base
    command: /code/run_worker

Service web dan worker sama-sama mewarisi instruksi build dan environment dari app-base, lalu masing-masing menambahkan instruksi command yang berbeda sesuai perannya. Cek hasil warisan konfigurasi ini lewat docker compose config untuk memastikan seluruh field dari app-base sudah tergabung dengan benar sebelum dijalankan.

docker compose config web

18.2.2 Batasan extends

Menurut Compose Specification, extends punya sejumlah batasan penting yang wajib kita pahami sebelum memakainya. Dependensi yang dideklarasikan lewat depends_on, links, volumes_from, atau referensi service:<nama> pada network_mode, ipc, maupun pid di service yang di-extend tidak otomatis ikut terbawa. Compose menyerahkan tanggung jawab itu ke kita untuk mendeklarasikan ulang dependensi tersebut secara eksplisit di service yang memakai extends, kalau memang dibutuhkan. Referensi melingkar (circular reference) antar service yang saling meng-extend satu sama lain juga tidak didukung dan akan membuat Compose langsung berhenti dengan error.

Batasan lain yang perlu diperhatikan adalah extends tidak berfungsi kalau aplikasi dijalankan lewat docker stack deploy; Compose akan menolak konfigurasi tersebut dengan pesan error configuration contains forbidden properties. Karena itu, pola extends paling cocok dipakai untuk deployment lewat docker compose biasa, bukan untuk aplikasi yang direncanakan berjalan di atas Docker Swarm.

18.3 Depends_on dan Startup Order

Compose selalu membuat dan menghentikan container mengikuti urutan dependensi yang ditentukan lewat depends_on, links, volumes_from, dan referensi network_mode: "service:...". Bagian ini membahas dua kondisi depends_on yang belum banyak dipakai pada aplikasi multi-container sederhana, yaitu menunggu proses selesai sepenuhnya dan menjaga service tetap sinkron saat dependensinya di-restart.

18.3.1 Menunggu Proses Selesai dengan service_completed_successfully

Sebagian aplikasi butuh proses inisialisasi satu kali sebelum service utama boleh berjalan, misalnya migrasi skema database. Kondisi service_completed_successfully pada depends_on membuat service dependen menunggu sampai service yang dituju keluar dengan exit code sukses, bukan sekadar menunggu container-nya start.

services:
  migrate:
    build: .
    command: ["./manage.py", "migrate"]
    restart: "no"

  app:
    build: .
    depends_on:
      migrate:
        condition: service_completed_successfully
    ports:
      - "3000:3000"

Service migrate di atas sengaja diberi restart: "no" karena tugasnya cuma berjalan sekali sampai selesai, bukan proses yang harus tetap hidup seperti service pada umumnya. Compose baru menjalankan app setelah migrate keluar dengan status sukses (exit code 0); kalau migrate gagal dan keluar dengan exit code error, app tidak akan pernah dijalankan. Pola one-shot service semacam ini lazim dipakai Developer untuk memastikan skema database selalu konsisten dengan versi aplikasi yang sedang di-deploy, tanpa perlu menjalankan migrasi secara manual di luar Compose.

18.3.2 Restart Otomatis Mengikuti Dependensi

Opsi restart: true di dalam sintaks panjang depends_on membuat Compose otomatis me-restart service dependen setiap kali dependensinya di-restart atau diperbarui lewat operasi Compose, seperti docker compose restart atau docker compose up ulang setelah konfigurasi berubah.

services:
  web:
    build: .
    depends_on:
      db:
        condition: service_healthy
        restart: true

  db:
    image: postgres:16-alpine
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      retries: 5

Fitur restart: true ini diperkenalkan sejak Docker Compose versi 2.17.0, jadi pastikan versi Compose yang dipakai sudah mendukungnya. Perlu dicatat bahwa opsi ini cuma berlaku untuk restart yang dipicu operasi Compose secara eksplisit, bukan restart otomatis oleh container runtime saat container mati sendiri karena crash. Tanpa opsi ini, kalau db di-restart manual sementara web sudah terlanjur membuka koneksi lama ke database, web bisa saja terus mempertahankan koneksi yang sudah putus tanpa tahu perlu menyambung ulang; pola ini membantu Sysadmin/DevOps Engineer menghindari kondisi tersebut tanpa perlu me-restart web secara manual setiap kali db diperbarui.

Saat proses shutdown, Compose membalik urutan startup: service yang bergantung pada service lain selalu dihentikan lebih dulu, baru dependensinya. Pada dua contoh di atas, app dan web masing-masing dihentikan sebelum migrate maupun db, sehingga service inti seperti database tetap hidup selama masih ada service lain yang mungkin membutuhkannya.

18.4 Perintah CLI Docker Compose

Selain up dan down yang sudah lazim dipakai, ada beberapa perintah docker compose lain yang sering dibutuhkan Developer maupun Sysadmin/DevOps Engineer saat mengoperasikan aplikasi multi-container sehari-hari.

18.4.1 Memantau Status dan Log

Perintah ps menampilkan seluruh service beserta status container-nya, sementara logs menampilkan output log dari service yang berjalan.

docker compose ps
docker compose logs -f app

Opsi -f pada logs membuat Compose terus menampilkan log baru secara real-time (follow mode), mirip perilaku tail -f, dan berhenti hanya kalau kita menghentikannya manual lewat Ctrl+C. Tanpa menyebut nama service, docker compose logs menampilkan log dari seluruh service sekaligus, yang di lapangan cukup membantu saat menelusuri urutan kejadian antar service ketika terjadi error yang melibatkan lebih dari satu service.

18.4.2 Menjalankan Perintah di Dalam Service

Perintah exec menjalankan perintah baru di dalam container service yang sedang berjalan, sedangkan run membuat container baru dari service yang sama untuk menjalankan tugas satu kali tanpa memengaruhi container yang sudah berjalan.

docker compose exec db psql -U postgres
docker compose run --rm app npm test

Opsi --rm pada run memastikan container sementara yang dibuat otomatis dihapus setelah perintahnya selesai, supaya container bekas testing atau task satu kali semacam ini tidak menumpuk dan memenuhi disk.

18.4.3 Rebuild dan Restart Service

Setelah mengubah Dockerfile atau source code yang dipakai instruksi build, kita perlu membangun ulang image lewat build, atau langsung menggabungkannya dengan up lewat opsi --build.

docker compose build app
docker compose up -d --build

Opsi --build pada up memaksa Compose membangun ulang image untuk setiap service yang memakai instruksi build sebelum container-nya dijalankan, sehingga kita tidak perlu menjalankan build dan up sebagai dua perintah terpisah. Untuk sekadar me-restart service tanpa membangun ulang image maupun mengubah konfigurasi, gunakan restart.

docker compose restart app

18.4.4 Membersihkan Resource

Perintah down menghentikan sekaligus menghapus seluruh container dan network yang dibuat Compose untuk project tersebut.

docker compose down

Secara default, down tidak menghapus named volume maupun image yang sudah dibangun, sehingga data di volume tetap aman kalau kita menjalankan up lagi setelahnya. Kalau kita menambahkan opsi -v, Compose juga menghapus seluruh named volume yang dideklarasikan di compose.yaml, dan tindakan ini bersifat destruktif serta tidak bisa dibatalkan.

docker compose down -v

Sebelum menjalankan down -v di environment mana pun yang menyimpan data penting seperti database production, pastikan sudah ada backup data yang valid, karena perintah ini langsung menghapus isi volume tanpa konfirmasi tambahan. Verifikasi konfigurasi project maupun keberadaan file Compose yang sedang dipakai kapan saja lewat perintah config yang sudah dibahas di bagian sebelumnya, terutama sebelum menjalankan perintah yang berpotensi destruktif seperti ini.