Docker Compose Watch

Docker Tutorials


Docker Compose Watch automatically updates development containers when files change on your computer. It can synchronize source files, rebuild an image, or restart a service, which removes the repeated stop-build-start cycle during local development.

Compose Watch is available in Docker Compose 2.22.0 and later. It works with services built from local source through the build attribute. It does not watch services that only use a pre-built image.

Check Your Docker Compose Version

Confirm that your Compose version supports Watch before adding rules.

Example:

# Display the installed Docker Compose version.
docker compose version

Upgrade Docker Desktop or the Compose plugin if the reported version is older than 2.22.0.

How Compose Watch Works

Watch rules belong under develop.watch for a service. Each rule identifies a local path and the action Docker should take when that path changes.

Action Behavior Best use
sync Copies changed files into the running container Source files used by a hot-reload process
rebuild Builds the image again and replaces the container Dependencies or compiled application changes
sync+restart Copies files and restarts the service Configuration changes that require a process restart

Create a Basic Watch Configuration

This Compose file synchronizes application source and rebuilds the service when its dependency file changes.

Example:

services:
  app:
    build: .
    command: ./start-dev
    develop:
      watch:
        # Copy source changes into the running container.
        - action: sync
          path: ./src
          target: /workspace/src
          initial_sync: true

        # Rebuild when application dependencies change.
        - action: rebuild
          path: ./dependencies.lock

The path is relative to the Compose project directory. Directories are watched recursively. The target identifies the corresponding destination inside the container.

Start Compose in Watch Mode

Use up --watch when you want application logs and watch activity in the same terminal.

Example:

# Build, start, and watch every configured service.
docker compose up --watch

If the stack is already running, start the dedicated watch command in another terminal.

Example:

# Monitor changes without mixing them with service logs.
docker compose watch

Synchronize Source Files

The sync action copies changed files without rebuilding the image. Use it when the process inside the container already supports reloading application code.

Example:

services:
  app:
    build: .
    develop:
      watch:
        - action: sync
          path: ./src
          target: /workspace/src
          initial_sync: true
          ignore:
            # Paths are relative to ./src.
            - cache/
            - "*.tmp"

initial_sync: true brings matching files up to date before a new watch session begins. Ignore patterns use the same pattern style as .dockerignore, but they are relative to the rule's path.

Rebuild When Dependencies Change

A dependency or build configuration change often requires a new image. Use a separate rebuild rule for that file.

Example:

develop:
  watch:
    - action: sync
      path: ./src
      target: /workspace/src

    # Changing the lock file rebuilds and replaces the service.
    - action: rebuild
      path: ./dependencies.lock

    - action: rebuild
      path: ./Dockerfile

A rebuild uses BuildKit and behaves like running docker compose up --build for the affected service. Organize the Dockerfile for effective layer caching so dependency rebuilds remain fast.

Synchronize and Restart Configuration

Use sync+restart when a configuration file can be copied directly but the service must restart before it reads the change.

Example:

services:
  gateway:
    build: ./gateway
    develop:
      watch:
        # Copy the configuration, then restart the service.
        - action: sync+restart
          path: ./gateway/service.conf
          target: /etc/gateway/service.conf

Prepare the Container Image

Compose Watch requires stat, mkdir, and rmdir inside the service image. The configured container user must also be able to write to each synchronization target.

Example:

FROM alpine:3.23

# Create a non-root user and writable working directory.
RUN adduser -D -u 1001 appuser
WORKDIR /workspace
COPY --chown=appuser:appuser . /workspace
USER appuser

CMD ["./start-dev"]

Tip: Use COPY --chown when the container runs as a non-root user. Otherwise, synchronization can fail because the target files belong to root.

Compose Watch and Bind Mounts

Watch does not replace every bind mount. Choose the mechanism that matches the development task.

Requirement Recommended approach
Selective source synchronization Compose Watch
Automatic rebuild after dependency changes Compose Watch
Sharing a large working directory exactly as-is Bind mount
Persistent database files Named volume

Common Problems

  • Nothing changes: Confirm the service uses build, not only image.
  • Permission denied: Give the container user write access to the target directory.
  • Too many events: Ignore generated files, caches, and dependency directories.
  • Unexpected path: Watch paths start at the project directory, while ignore patterns start at the rule path.
  • Slow rebuilds: Copy dependency files before source files in the Dockerfile to improve cache reuse.

Conclusion

Docker Compose Watch creates a faster container-based development loop. Use sync for ordinary source changes, rebuild for dependencies and build files, and sync+restart for configuration. Clear paths, suitable ignore rules, and correct container permissions keep the workflow reliable.



Found This Page Useful? Share It!
Get the Latest Tutorials and Updates
Join us on Telegram