Compose Watch makes the response to a source change explicit
Desktop 4.24 makes Compose Watch available to all users. Its sync and rebuild actions let a project distinguish source edits from changes that require a new image.
A source edit and a dependency change often need different responses in a containerized development environment. Copying changed source into a running service can be sufficient when its development process reloads that source. A changed installation input may require rebuilding the image. Docker Desktop 4.24, released September 28, makes Compose Watch available to all users, giving those choices a place in the service definition.
The release includes Compose 2.22.0. Its watch implementation distinguishes synchronization from rebuilding and maps changed host paths to container paths. The useful idea is that the development workflow can describe the intended response to a file change. A single undifferentiated directory mount does not express the same decision.
I value repeatable build files, and development configuration needs a similarly explicit account of how changes reach the running service. A quick source-update path is useful when the eventual image build remains understandable. Watch gives those operations separate names without requiring each application to assemble its own file-event dispatcher.
The service declares its development behavior
The Compose 2.22.0 implementation reads the service's develop configuration. It also recognizes the earlier x-develop extension and prints a deprecation warning for it. That transition matters to projects that experimented with the feature before it became generally available.
An illustrative service can synchronize its source directory and rebuild when its dependency manifest changes. The example assumes a Dockerfile in the project root and a development process that reads application files beneath /app. It demonstrates the watch rules, not a complete application or a claim about every framework's reload behavior.
services:
web:
build: .
develop:
watch:
- action: sync
path: ./src
target: /app/src
- action: rebuild
path: ./package.json
The two paths express different construction assumptions. Source files can be updated in place for this hypothetical development process. The dependency manifest participates in creating the image, so its change takes the rebuild route. A project using additional dependency inputs needs corresponding rules for those inputs. The configuration should reflect the actual application rather than the brevity of the example.
The implementation rejects watch configuration on a service without a build context. This is a specific requirement in the shipped version. It is not sufficient to point Watch at any arbitrary image-only service and expect the same workflow. The service definition has to supply the construction context that the watch mechanism requires.
Synchronization maps paths
For each accepted event, the code computes the path relative to the watched host directory. It joins that relative path to the container target, using Unix-style paths inside the container. A host file beneath src consequently has a corresponding location beneath the configured target. This mapping is what makes the source directory rule more precise than a request to copy an unspecified project tree.
The target is a location the application must actually use. Synchronizing files into an unused directory cannot make the process observe them. Similarly, a process that only reads a file at startup does not become a reloading process because a file changed. Watch performs the configured update, while application behavior determines what that update means to the service.
That separation is useful when diagnosing a development loop. One question is whether the changed file reached the expected container path. Another is whether the running process responds to that file. Treating those as separate stages gives a more concrete investigation than assuming every stale response means file watching failed.
The default synchronization implementation in this release is tar-based. The code retains a Docker-copy alternative behind an environment setting. This detail illustrates that synchronization is an implemented transfer operation with its own behavior. It is not simply another spelling of a host directory bind mount.
Rebuilds operate on the affected service
When a batch contains a rebuild event, Compose calls its application-update operation with the build restricted to that service. The source comments explicitly distinguish the service from its dependencies. The watch event therefore does not inherently ask Compose to rebuild every supporting service in the application.
That scope is useful for a project with a slow dependency build or a database image that is unrelated to the source change. The changed service owns the relevant construction work. A project that needs a coordinated change across several services must describe those relationships through its configuration and workflow, rather than assuming one watched file rebuilds everything.
Rebuilding also changes the artifact being exercised. An in-place source synchronization modifies the running development filesystem. A rebuild derives a new image through the build definition. Both can be appropriate in one workflow, but they answer different questions about whether a particular state can be reproduced from the Dockerfile and its inputs.
I prefer to keep that distinction visible when evaluating a development tool. The short edit loop should help a developer work on the service. The image build should still explain how to construct the deliverable. Watch's separate actions let a project state which changes require returning to that construction process.
File selection includes existing ignore rules
Compose loads .dockerignore rules from the service's build context. The implementation combines them with exclusions for ephemeral files and the .git directory. Per-trigger ignore rules provide another filter when events are matched. This makes the watched input set more specific than every file beneath a project directory.
Ignoring a file affects whether Watch sees a relevant change. A rule intended to keep generated output out of the build can also matter to the development workflow. Reading the ignore configuration alongside the watch declaration is necessary to understand the effective behavior. Looking at the watch path alone leaves out part of the selection process.
The implementation also checks whether a watched path is already covered by a bind mount. It warns and skips monitoring that path when it detects the overlap. This avoids treating the same directory as two independent file-update mechanisms. The relevant choice belongs to the directory's configuration, rather than to an assumption that adding Watch is always cumulative.
That behavior is particularly useful when adapting an existing Compose application. A project may already have development mounts that serve a similar purpose. Its final configuration needs a clear account of which mechanism supplies each directory. A watch rule can be present in the file yet be skipped because the mount already covers its path.
Batching prevents one operation per filesystem event
The code batches events using a quiet period of 500 milliseconds. Repeated identical events update their recorded time within the batch. After the quiet interval, the accumulated changes are handled together. This accommodates the fact that one editing action can produce several filesystem notifications.
Batching changes the unit of work from a raw notification to a set of changes. It also explains why the visible response need not begin at the instant the editor saves a file. The dispatcher is waiting for the configured quiet period before acting. This is a specific property of the release implementation, not a timing guarantee for completion of the subsequent build or transfer.
The versioned command reference describes docker compose watch as watching the build context and refreshing or rebuilding containers. Its --no-up option skips the initial build and startup. That option changes initialization of the workflow, while the file rules continue to determine how later changes are handled.
The implementation reports synchronization batches with the affected service and changed paths. It also prints a separate rebuilding message when a rebuild event determines the operation. Those messages help connect the visible update to the rule that selected it. A developer investigating an unexpected rebuild can therefore compare the reported changed file with the configured trigger, instead of inferring the action solely from container behavior. The configuration and the dispatch message describe different stages of the same update.
Desktop also changes idle behavior
The Desktop release separately makes Resource Saver available to all users and enables it by default. It also adds dashboard controls for pausing, stopping and resuming the Engine. These concern the lifecycle and resource cost of the local environment, while Watch concerns updates to the services running within it.
For a project adopting Watch, the useful deliverable is a development configuration whose paths and actions match the application. The ignore rules determine which changes qualify. Synchronization maps those changes into container paths, and rebuild events return the affected service to its image construction process. Application reload behavior remains a property of the process receiving the updated files.