Live Reload ohne Bind Mount Krücken
Wer lokale Entwicklungsumgebungen mit Docker Compose betreibt, kennt das Problem: Ein Bind Mount spiegelt alles, aber node_modules, Vendor-Verzeichnisse und Build-Artefakte sorgen fuer Performance-Probleme und Konflikte zwischen Host und Container. Docker Compose Watch loest das gezielt mit drei Aktionen, sync, rebuild und sync und restart, und macht Live Reload endlich vorhersehbar.
Inhaltsverzeichnis
- 1. Warum Docker Compose Watch existiert
- 2. Grundkonfiguration: die watch Direktive verstehen
- 3. Aktion sync: Dateien ohne Neustart spiegeln
- 4. Aktion rebuild: Images bei Abhaengigkeitsaenderungen neu bauen
- 5. Aktion sync und restart: Konfigurationsdateien sauber uebernehmen
- 6. Praxisbeispiel: Node.js Frontend mit Live Reload
- 7. Praxisbeispiel: PHP und Magento mit compose watch
- 8. Grenzen, Ignore-Regeln und Debugging
- 9. compose watch im Vergleich zu Bind Mounts und externen Tools
- 10. Zusammenfassung
- 11. FAQ
1. Warum Docker Compose Watch existiert
Vor Docker Compose Watch gab es fuer Live Reload in Containern im Wesentlichen nur einen Weg: einen Bind Mount des kompletten Projektverzeichnisses in den Container legen und hoffen, dass der Rest funktioniert. Das Problem dabei ist, dass ein Bind Mount keine Unterscheidung kennt. Er spiegelt Quellcode genauso wie node_modules, Vendor-Verzeichnisse, Build-Caches und temporaere Dateien, und das fuehrt vor allem auf macOS und Windows zu spuerbaren Performance-Einbruechen, weil jede Dateisystemoperation ueber die virtualisierte Schicht laufen muss.
Docker Compose Watch loest dieses Problem, indem es die Synchronisation explizit macht. Statt eines pauschalen Mounts definiert man in der compose.yaml gezielt, welche Pfade beobachtet werden sollen und welche Aktion bei einer Aenderung ausgeloest wird. Das Ergebnis ist ein Live Reload Setup, das nur die tatsaechlich relevanten Dateien synchronisiert, waehrend node_modules oder vendor komplett im Container bleiben und dort mit nativer Geschwindigkeit verwaltet werden. Fuer Teams, die taeglich mit Docker Compose arbeiten, ist das ein spuerbarer Sprung in der Entwicklungserfahrung.
Ein weiterer Vorteil von compose watch gegenueber klassischen Bind Mounts: Die Konfiguration liegt direkt in der compose.yaml und ist damit Teil des Projekts, versioniert und fuer jeden Entwickler identisch. Niemand muss mehr manuell Volumes anpassen oder externe Tools wie nodemon oder browser-sync separat konfigurieren, um Aenderungen zu erkennen. Docker Compose selbst uebernimmt das File-Watching und entscheidet anhand der definierten Regeln, ob synchronisiert, neu gebaut oder neu gestartet werden muss.
2. Grundkonfiguration: die watch Direktive verstehen
Die watch Direktive wird pro Service unter dem Schluessel develop.watch definiert. Jeder Eintrag in dieser Liste beschreibt einen Pfad, eine Aktion und optionale Filter. Der path gibt an, welches Verzeichnis oder welche Datei relativ zur compose.yaml beobachtet wird. Die action bestimmt, was bei einer Aenderung passiert, moeglich sind sync, rebuild und sync und restart. Optional laesst sich mit target angeben, wohin im Container synchronisiert werden soll, falls sich das vom Quellpfad unterscheidet.
Gestartet wird compose watch mit docker compose watch, wahlweise parallel zu einem laufenden docker compose up oder kombiniert ueber docker compose up --watch in einem einzigen Befehl. Wichtig fuer den produktiven Einsatz im Entwicklungsalltag: compose watch beobachtet ausschliesslich Aenderungen auf dem Host-Dateisystem, es ersetzt keine Healthchecks und keine Orchestrierung, sondern ergaenzt einen bereits laufenden Compose-Stack um File-Watching-Funktionalitaet.
# compose.yaml — minimal watch configuration
services:
web:
build: .
ports:
- "3000:3000"
develop:
watch:
# Sync source files without rebuilding the image
- action: sync
path: ./src
target: /app/src
# Rebuild the image when dependency files change
- action: rebuild
path: ./package.json
# Sync config and restart the process (no image rebuild)
- action: sync+restart
path: ./config
target: /app/config
Diese drei Aktionstypen decken die typischen Aenderungsfaelle in einer modernen Anwendung fast vollstaendig ab. Quellcode aendert sich staendig und braucht nur eine schnelle Synchronisation. Abhaengigkeiten aendern sich seltener, erfordern aber einen vollstaendigen Rebuild, weil sich die Image-Schichten aendern. Konfigurationsdateien aendern sich gelegentlich und brauchen einen Prozessneustart, aber kein neues Image. Docker Compose Watch bildet genau diese drei Faelle ab, ohne dass ein Entwickler eigene Skripte fuer File-Watching schreiben muss.
3. Aktion sync: Dateien ohne Neustart spiegeln
Die Aktion sync ist die haeufigste und leichtgewichtigste Option von Docker Compose Watch. Sobald sich eine Datei im beobachteten Pfad aendert, kopiert Compose die Aenderung direkt in den laufenden Container, ohne das Image neu zu bauen und ohne den Container neu zu starten. Fuer Entwicklungssetups mit Hot Module Replacement, etwa Vite, Webpack Dev Server oder Node mit nodemon im Container, reicht das vollstaendig aus, weil der Prozess im Container selbst auf die Dateisystemaenderung reagiert.
Wichtig bei sync ist die Unterscheidung zwischen path und target. Der path bezieht sich immer auf den Host, relativ zur compose.yaml, waehrend target den absoluten Zielpfad im Container angibt. Diese Trennung erlaubt es, unterschiedliche Verzeichnisstrukturen zwischen Host und Container zu haben, was besonders bei Monorepos oder wenn das Arbeitsverzeichnis im Image von der lokalen Struktur abweicht, sehr praktisch ist. Ohne target uebernimmt Compose Watch den gleichen relativen Pfad wie im Container-Working-Directory definiert.
Ein haeufiger Fehler beim Einsatz von sync ist, dass Entwickler versuchen, node_modules oder vendor ueber sync zu synchronisieren. Das funktioniert technisch, ist aber langsam und unnoetig, weil diese Verzeichnisse ohnehin im Image liegen sollten und sich nur bei einer Aenderung des package.json oder composer.json aendern muessen, wofuer die Aktion rebuild vorgesehen ist. Der Grundsatz lautet: sync fuer Quellcode, rebuild fuer Abhaengigkeiten.
4. Aktion rebuild: Images bei Abhaengigkeitsaenderungen neu bauen
Wenn sich eine Datei aendert, die Einfluss auf den Build-Prozess hat, etwa package.json, package-lock.json, composer.json oder das Dockerfile selbst, reicht eine reine Synchronisation nicht aus. Hier kommt die Aktion rebuild ins Spiel. Compose Watch erkennt die Aenderung, baut das Image mit docker compose build neu und startet den betroffenen Service anschliessend automatisch neu, ohne dass ein manueller Eingriff noetig ist.
Der Vorteil gegenueber einem manuellen docker compose up --build liegt in der Automatisierung des gesamten Zyklus. Sobald ein Entwickler eine neue Abhaengigkeit installiert und die package.json speichert, laeuft der Rebuild automatisch im Hintergrund, waehrend Compose Watch weiterhin auf weitere Aenderungen achtet. Das reduziert den Kontextwechsel erheblich, weil Entwickler nicht mehr manuell zwischen Editor und Terminal wechseln muessen, um einen Rebuild anzustossen.
# compose.yaml — rebuild triggers for dependency changes
services:
api:
build:
context: .
dockerfile: Dockerfile
develop:
watch:
- action: sync
path: ./src
target: /app/src
# Any change to these files triggers a full image rebuild
- action: rebuild
path: ./package.json
- action: rebuild
path: ./package-lock.json
- action: rebuild
path: ./Dockerfile
Ein wichtiger Hinweis: Rebuild-Zyklen sollten bewusst sparsam eingesetzt werden, weil jeder Rebuild Zeit kostet, selbst mit BuildKit-Caching. Nur Dateien, die tatsaechlich Layer-Aenderungen im Image ausloesen, gehoeren in eine rebuild Regel. Quellcode, der sich waehrend der Entwicklung staendig aendert, sollte immer ueber sync laufen, niemals ueber rebuild, sonst verliert Docker Compose Watch genau den Geschwindigkeitsvorteil, fuer den es entwickelt wurde.
5. Aktion sync und restart: Konfigurationsdateien sauber uebernehmen
Zwischen sync und rebuild liegt ein dritter Fall, der in der Praxis sehr haeufig vorkommt: Dateien, die keinen Rebuild des Images erfordern, aber einen Neustart des Prozesses im Container, damit die Aenderung wirksam wird. Typische Beispiele sind Umgebungskonfigurationen, PHP-Ini-Dateien, Nginx-Konfigurationen oder Server-Startskripte, die beim Prozessstart eingelesen werden, aber nicht bei jeder Dateisystemaenderung neu geladen werden.
Fuer genau diesen Fall gibt es die Aktion sync und restart. Compose Watch kopiert die Datei zunaechst wie bei sync in den Container und startet danach den Container neu, sodass der Prozess mit der aktualisierten Konfiguration hochfaehrt. Der entscheidende Unterschied zu rebuild ist, dass kein neues Image gebaut wird, sondern lediglich der bestehende Container neu gestartet wird, was deutlich schneller ist als ein vollstaendiger Build-Zyklus.
# compose.yaml — sync+restart for config that needs a process reload
services:
php:
build: .
develop:
watch:
- action: sync
path: ./src
target: /var/www/html/src
# Config changes need a restart but not a rebuild
- action: sync+restart
path: ./docker/php.ini
target: /usr/local/etc/php/conf.d/custom.ini
- action: sync+restart
path: ./docker/nginx.conf
target: /etc/nginx/conf.d/default.conf
In der Praxis empfiehlt es sich, alle drei Aktionen bewusst nach ihrer Kostenreihenfolge zu betrachten. sync ist am guenstigsten, sync und restart kostet einen Prozessneustart, rebuild kostet einen vollstaendigen Image-Build. Wer diese Reihenfolge im Kopf hat, findet fuer jede Datei im Projekt schnell die passende Kategorie und vermeidet unnoetig lange Wartezeiten waehrend der Entwicklung mit Docker Compose Watch.
6. Praxisbeispiel: Node.js Frontend mit Live Reload
Ein typisches Node.js Frontend mit Vite oder Webpack Dev Server profitiert besonders stark von Docker Compose Watch, weil der Dev Server selbst bereits Hot Module Replacement beherrscht, sobald Dateien im Container aktualisiert werden. Die Aufgabe von compose watch beschraenkt sich hier darauf, Aenderungen aus dem Host-Editor zuverlaessig und schnell in den Container zu bringen, ohne dass node_modules jemals ueber das Netzwerk oder die virtualisierte Dateisystemschicht synchronisiert werden muessen.
Wichtig ist, node_modules im Container zu belassen und nicht ueber einen klassischen Bind Mount vom Host zu ueberschreiben. Das erreicht man, indem man im Dockerfile npm install ausfuehrt und in der compose.yaml kein Volume fuer node_modules definiert, sondern nur sync fuer den src-Ordner konfiguriert. Aendert sich die package.json, greift automatisch die rebuild Regel, und die Abhaengigkeiten werden im Image neu installiert.
# Start the stack and watch mode together in one command
docker compose up --watch
# Or run watch mode against an already running stack
docker compose up -d
docker compose watch
# Check which services are configured for watch mode
docker compose config --services
7. Praxisbeispiel: PHP und Magento mit compose watch
Bei PHP-Projekten, insbesondere bei Magento-Shops mit vielen Modulverzeichnissen, ist Docker Compose Watch ebenfalls sehr wirksam, muss aber praeziser konfiguriert werden als bei einem einzelnen Node-Prozess. PHP-FPM liest Dateien bei jedem Request neu ein, solange OPcache im Entwicklungsmodus laeuft, sodass eine reine sync Aktion fuer app/code oder src bereits ausreicht, um Codeaenderungen sofort sichtbar zu machen.
Fuer Vendor-Abhaengigkeiten, die ueber composer.json verwaltet werden, greift wieder die rebuild Regel, weil composer install Layer im Image veraendert. Konfigurationsdateien wie php.ini Overrides oder Xdebug-Einstellungen gehoeren in die sync und restart Kategorie, weil PHP-FPM diese Werte nur beim Prozessstart einliest. So entsteht ein Setup, in dem Entwickler an Magento-Modulen arbeiten koennen, waehrend Compose Watch im Hintergrund automatisch entscheidet, ob synchronisiert, neu gestartet oder neu gebaut werden muss.
# compose.yaml — PHP/Magento watch setup
services:
php-fpm:
build: ./docker/php
develop:
watch:
- action: sync
path: ./src/app/code
target: /var/www/html/app/code
- action: rebuild
path: ./composer.json
- action: sync+restart
path: ./docker/php/conf.d
target: /usr/local/etc/php/conf.d
8. Grenzen, Ignore-Regeln und Debugging
Docker Compose Watch ist kein universelles File-Watching-System und kennt einige Grenzen, die man kennen sollte, bevor man sich vollstaendig darauf verlaesst. Sehr grosse Verzeichnisse mit tausenden Dateien koennen die Erkennungsgeschwindigkeit beeinflussen, besonders wenn keine Ignore-Regeln definiert sind. Ueber ignore Eintraege innerhalb eines watch Blocks lassen sich Unterverzeichnisse wie node_modules, vendor oder .git gezielt ausschliessen, selbst wenn sie technisch innerhalb eines beobachteten Pfads liegen.
Fuer das Debugging von compose watch selbst hilft der Parameter --verbose, der jede erkannte Dateisystemaenderung und die daraus resultierende Aktion protokolliert. Das ist besonders hilfreich, wenn eine erwartete Synchronisation nicht ausgeloest wird, weil zum Beispiel ein Symlink oder ein Editor mit atomarem Speichern ueber eine temporaere Datei die Aenderungserkennung umgeht. In solchen Faellen hilft es oft, die betroffene Datei direkt anzufassen und den touch Befehl zu nutzen, um zu pruefen, ob die watch Regel grundsaetzlich funktioniert.
Eine weitere Einschraenkung: compose watch ersetzt keine produktiven Deployment-Mechanismen. Es ist ausschliesslich fuer die lokale Entwicklung gedacht und sollte niemals in produktiven compose.yaml-Dateien aktiv sein, weil das automatische Neustarten und Neubauen von Containern in einer Produktionsumgebung unkontrollierbare Nebenwirkungen haben kann.
9. compose watch im Vergleich zu Bind Mounts und externen Tools
Vor Docker Compose Watch loesten Teams das Live Reload Problem meist mit einer Kombination aus Bind Mounts und externen Tools wie nodemon, entr oder eigenen Shell-Skripten, die inotify direkt ansprachen. Diese Loesungen funktionieren, bringen aber zusaetzliche Komplexitaet mit, weil sie ausserhalb der compose.yaml konfiguriert und gewartet werden muessen und oft nicht plattformuebergreifend gleich funktionieren.
| Ansatz | Konfigurationsort | node_modules Problem | Plattform-Konsistenz |
|---|---|---|---|
| Klassischer Bind Mount | compose.yaml (volumes) | Alles wird gespiegelt, langsam | macOS/Windows deutlich langsamer |
| nodemon im Container | separates Config-File | Muss separat ausgeschlossen werden | Abhaengig vom Bind Mount darunter |
| Eigenes inotify Skript | externes Shell-Skript | Manuell zu pflegen | Nur Linux nativ, sonst fragil |
| Docker Compose Watch | compose.yaml (develop.watch) | Bleibt im Image, kein Sync noetig | Einheitlich ueber Compose Engine |
Der entscheidende Unterschied ist, dass Docker Compose Watch die Synchronisationslogik in die Compose Engine selbst integriert, statt sie ueber Bind Mounts und zusaetzliche Prozesse im Container zu loesen. Damit wird die Konfiguration Teil der versionierten compose.yaml, jeder Entwickler im Team bekommt automatisch dieselbe Live Reload Erfahrung, und es entfaellt die Notwendigkeit, Watcher-Tools und deren Ignore-Listen manuell im Image zu pflegen.
Mironsoft
Docker-Entwicklungsumgebungen und Container-Infrastruktur
Live Reload, das im ganzen Team gleich funktioniert?
Wir richten Docker Compose Watch fuer eure Entwicklungsumgebung ein, entfernen fragile Bind Mounts und sorgen dafuer, dass Node-, PHP- und Magento-Stacks schnell und zuverlaessig neu laden.
Setup-Audit
Bestehende compose.yaml auf Bind-Mount-Probleme und fehlende Ignore-Regeln pruefen
Watch-Konfiguration
sync, rebuild und sync und restart passend zum Projekt einrichten
Magento-Docker
Live Reload fuer PHP-FPM, Nginx und Node-Build-Prozesse in einem Stack
10. Zusammenfassung
Docker Compose Watch loest ein Problem, das lokale Entwicklungsumgebungen mit Bind Mounts seit Jahren begleitet: die unkontrollierte Spiegelung ganzer Verzeichnisse inklusive node_modules und vendor. Mit den drei Aktionen sync, rebuild und sync und restart laesst sich fuer jede Datei im Projekt gezielt festlegen, wie eine Aenderung behandelt wird, ohne dass externe Watcher-Tools noetig sind. Quellcode wird schnell synchronisiert, Abhaengigkeitsaenderungen loesen automatisch einen Rebuild aus, und Konfigurationsdateien fuehren zu einem gezielten Neustart des betroffenen Containers.
Der groesste Vorteil liegt in der Konsistenz im Team: Die watch Konfiguration liegt versioniert in der compose.yaml, jeder Entwickler bekommt dieselbe Live Reload Erfahrung, unabhaengig vom Betriebssystem. Wer node_modules und vendor konsequent im Image belaesst und nur echten Quellcode ueber sync synchronisiert, gewinnt spuerbar an Geschwindigkeit gegenueber klassischen Bind Mount Setups, besonders auf macOS und Windows.
Docker Compose Watch — Das Wichtigste auf einen Blick
sync
Kopiert Dateiaenderungen direkt in den laufenden Container, ideal fuer Quellcode mit Hot Module Replacement.
rebuild
Baut das Image bei Aenderungen an package.json oder Dockerfile automatisch neu und startet den Service neu.
sync+restart
Synchronisiert Konfigurationsdateien und startet den Prozess neu, ohne ein neues Image zu bauen.
Ignore-Regeln
node_modules, vendor und .git ueber ignore ausschliessen, um Erkennungsgeschwindigkeit zu erhalten.