Docker Compose Watch, a tool to improve the inner loop of application development, is now generally available. Hot reload is one of those engineering workflow features that’s seemingly minor and simple but has cumulative benefits. If you can trust your app will update seamlessly as you code, without losing state, it’s one less thing pulling your focus from the work at hand. You can see your frontend components come to life while you stay in your IDE.
With containerized application development, there are more steps than Alt+Tab and hitting reload in your browser. Even with caching, rebuilding the image and re-creating the container — especially after waiting on stop and start time — can disrupt focus.
We built Docker Compose Watch to smooth away these workflow papercuts. We have learned from many people using our open source Docker Compose project for local development. Now we are natively addressing common workflow friction we observe, like the use case of hot reload for frontend development.
Bind mount vs. Watch
A common workaround to get hot reload to work is to set up a bind mount to mirror file changes between the local system and a container. This method uses operating system and hypervisor APIs to expose a local directory to the otherwise isolated file system in the container.
The workaround is not trivial engineering since how bind mounts function in Docker Desktop differs from Docker Engine on Linux. For parity, Docker Desktop must provide seamless and efficient file sharing between your machine and its virtual machine (VM), ensuring permissions, replicating file notifications, and maintaining low-level filesystem consistency to prevent corruption.
In contrast, Docker Compose Watch is specifically targeting development use cases. You may want to ensure your code changes sync into the container, allowing React or NextJS to kick off its own live reload. However, you don’t want the changes you’ve made in the container for ad-hoc testing to reflect in your local directory. For this reason, the tradeoffs we make for Docker Compose Watch favor fine-grained control for common development workflows with Docker Compose (Figures 1 and 2).
Improving Watch for development
Since the alpha launch (in Compose v2.17, bundled with Docker Desktop 4.18), we’ve responded to early feedback by making Docker Compose Watch faster and more robust. This improvement avoids hiccups on common development tasks that kick off many changes, such as merging in the latest main or switching branches.
Your code sync operation now batches, debounces, and ignores unimportant changes:
- What previously would be many API calls are now batched as a single API call to the Docker Engine.
- We’ve fine-tuned the streaming of changes to your containers for improved transfer performance. A new built-in debounce mechanism prevents unnecessary transfers in case of back-to-back writes to the same file. This optimizes CPU usage by preventing unnecessary incremental compiles.
- The built-in filters have been refined to ignore standard temporary files generated by common code editors and integrated development environments (IDEs).
Previously, Docker Compose Watch required attaching to an already running Compose project. Docker Compose Watch now automatically builds and starts all required services at launch. One command is all you need:
docker compose watch.
Try Docker Compose Watch in Docker Desktop 4.24
As of Compose 2.22.0, bundled with Docker Desktop 4.24, Docker Compose Watch is now Generally Available. Make sure to upgrade to the latest version of Docker Desktop and develop more efficiently with
docker compose watch.