Docker Compose Watch: Feedback Instan untuk Dev Container Lokal

Foto oleh Florian Olivo

Foto oleh Florian Olivo
Bertahun-tahun workflow container lokal saya punya pajak di setiap perubahan: edit file, pindah ke terminal, jalankan docker compose up --build, tunggu tiga puluh detik sampai dua menit, lalu cek browser. Kalikan dengan sekitar delapan puluh perubahan yang saya buat dalam satu sore yang fokus, dan saya membuang banyak waktu hanya untuk menunggu rebuild. Docker Compose Watch menghapus pajak itu hampir seluruhnya, dan fiturnya sudah ada di binary Compose yang Anda pakai sekarang.
Jawaban singkat untuk Anda yang sedang mencari: tambahkan blok develop.watch ke compose.yaml, deklarasikan path mana yang harus sync, rebuild, atau sync+restart, lalu jalankan docker compose up --watch. Compose Watch resmi GA di Compose v2.22.0 (dibundel dengan Docker Desktop 4.24), jadi kalau Anda pernah update Docker sejak akhir 2023, fiturnya sudah tersedia. Di artikel ini saya akan membahas cara saya memakainya untuk setup API NestJS plus worker, di mana ia mengalahkan bind mount, dan gotcha yang sempat menggigit saya di proyek nyata.
Sebelum Watch, ada dua opsi untuk kode live di dalam container, dan keduanya punya sisi tajam:
Compose Watch mengambil jalan ketiga: ia mengamati file di host dan menyalin perubahan satu arah ke container yang sedang berjalan. Image Anda tetap menjadi satu-satunya sumber kebenaran untuk dependency dan library sistem, sementara source code mengalir masuk saat Anda menekan save. Perubahan di sisi container tidak pernah bocor balik ke host, dan itu persis arah trust yang Anda inginkan saat development.
Setiap aturan watch memasangkan sebuah path dengan sebuah action. Memilih action yang tepat per path adalah sumber percepatan sesungguhnya, karena action termurah yang tetap menghasilkan container yang benar adalah pemenangnya.
| Action | Apa yang dilakukan | Kapan saya memakainya |
|---|---|---|
| sync | Menyalin file yang berubah ke container berjalan di path target, tanpa me-restart apa pun. | Source code di framework apa pun dengan hot reload: NestJS dengan webpack HMR, Next.js, Vite, script yang diawasi nodemon. |
| rebuild | Membangun ulang image dengan BuildKit dan mengganti container yang berjalan, seperti docker compose up --build untuk service itu. | package.json, lockfile, Dockerfile, apa pun yang terpanggang ke dalam layer image. Juga bahasa terkompilasi seperti Go di mana binary adalah artefaknya. |
| sync+restart | Menyalin file yang berubah, lalu me-restart proses container tanpa membangun ulang image. | File konfigurasi yang dibaca sekali saat boot: file .env, nginx.conf, ormconfig. Image-nya tidak masalah, prosesnya saja yang perlu start ulang. |
Berikut versi ringkas dari setup yang saya jalankan untuk API NestJS plus background worker. Perhatikan bagaimana setiap path mendapat action termurah yang masih layak, dan bagaimana ignore mencegah file test memicu sync yang sia-sia:
# compose.yaml — NestJS API + worker, watch-enabled
services:
api:
build: ./api
ports:
- "3000:3000"
develop:
watch:
# hot-reload source straight into the container
- path: ./api/src
target: /app/src
action: sync
# dependency changes need a real rebuild
- path: ./api/package.json
action: rebuild
# config tweak? just restart the process
- path: ./api/.env.development
action: sync+restart
target: /app/.env.development
worker:
build: ./worker
develop:
watch:
- path: ./worker/src
target: /app/src
action: sync
ignore:
- "**/*.spec.ts"Lalu jalankan semuanya dengan watch aktif:
docker compose up --watch
# or, to run watch without attaching logs:
docker compose watchPro tip: tetap pakai docker compose up --watch (satu terminal, log dan watch jadi satu) sampai stack Anda membesar. Dengan lebih dari tiga atau empat service, pisahkan log ke terminal lain dengan docker compose logs -f api supaya notifikasi sync tidak menenggelamkan output aplikasi Anda.
Saya masih sering ditanya kenapa tidak mount saja direktori source dan selesai. Ini perbandingan jujurnya setelah menjalankan kedua pendekatan di proyek klien dan aplikasi saya sendiri yang di-deploy ke VPS:
Compose Watch
Sync satu arah dari host ke container. node_modules tetap milik container, dibangun untuk Linux di dalam image. File temp editor otomatis difilter, dan save beruntun di-debounce menjadi transfer batch. Lingkungan dev sangat dekat dengan perilaku image production.
Bind mount
Dua arah secara default, jadi tulisan dari container mengotori tree di host Anda. node_modules host menutupi milik image kecuali Anda menambah trik anonymous volume. I/O lebih lambat lewat batas VM macOS/Windows. Masih oke untuk eksperimen cepat dan proyek satu service.
Aturan praktis saya: bind mount untuk prototyping sekali pakai, Compose Watch untuk apa pun yang punya Dockerfile dan kelak akan dirilis. Action sync memberi kecepatan feedback selevel bind mount sambil menjaga image sebagai kontrak, dan kontrak itulah yang membuat lompatan dari laptop ke node production Docker Swarm saya terasa membosankan, dan memang itu tujuannya.
Jangan arahkan action sync ke package.json dengan harapan dependency ikut terinstall. Sync hanya menyalin file; node_modules di container tidak akan berubah. Manifest dependency tempatnya di action rebuild, titik.
Compose Watch adalah salah satu fitur quality-of-life yang diam-diam balik modal dalam satu jam pertama. Loop terukur saya di codebase NestJS ukuran menengah turun dari sekitar 45 detik per perubahan dengan rebuild menjadi di bawah dua detik dengan sync plus webpack HMR, dan tidak seperti bind mount, saya tidak menukar fidelitas environment untuk mendapatkannya.
Kalau tim Anda masih rebuild image di setiap save, atau berkelahi dengan hantu node_modules dari bind mount, luangkan lima belas menit itu. Permukaan konfigurasinya cuma tiga action dan satu daftar ignore. Itu saja seluruh fiturnya, dan itu sudah cukup.
Sumber dan bacaan lanjutan