How do you share data between multiple containers?
Quick Answer
Mount the same named volume (or the same bind-mounted host path) into more than one container — since a volume isn't exclusively owned by any single container, any number of containers can mount and read/write the same underlying data simultaneously, as long as the application-level access pattern is safe for concurrent access. This is the standard way to share files between, for example, a main application container and a sidecar-style helper container (mirroring the same pattern covered in the Kubernetes stack's sidecar question).
Detailed Answer
Mounting the same volume into multiple containers
docker volume create shared-logs
docker run -d --name app -v shared-logs:/app/logs myapp:1.0
docker run -d --name log-shipper -v shared-logs:/logs:ro fluent-bit
Both containers mount the same named volume (shared-logs). app writes its log files there. log-shipper reads and forwards them elsewhere; it is mounted read-only via :ro, since it should never need to modify the application's own logs. Neither container needs any special awareness of the other. They are simply both pointed at the same underlying storage.
Why this is the standard technique for sidecar-style patterns
This is conceptually identical to the sidecar container pattern covered in the Kubernetes stack. A helper container (log shipping, a cache-warming process, a file-processing pipeline) shares data with a main application container purely through a commonly mounted volume. Neither container needs direct knowledge of the other's internals — just an agreed-upon shared directory structure and file format.
# Example: an init-container-like pattern using plain Docker + Compose,
# where one container prepares data that another then serves
docker volume create shared-content
docker run --rm -v shared-content:/output content-fetcher:1.0 # populates the volume, then exits
docker run -d -v shared-content:/usr/share/nginx/html nginx # serves what was fetched
Read-only mounts for safety
docker run -v shared-data:/data:ro myapp
When a container only needs to read shared data, not modify it, mounting the volume read-only (:ro) is good practice. It prevents that container from accidentally (or maliciously, if compromised) corrupting data another container depends on. This is a straightforward application of least privilege at the storage layer.
The concurrency caveat: Docker doesn't handle file-level locking for you
Container A writes to shared-file.json
Container B reads shared-file.json AT THE SAME MOMENT
Mounting the same volume into multiple containers gives them shared access to the same underlying files. But Docker itself provides no automatic coordination, locking, or consistency guarantees beyond whatever the underlying filesystem itself provides. If multiple containers might concurrently write to the exact same file, the application(s) involved are responsible for handling that safely — via file locking, an actual database instead of raw files, or a design where only one container ever writes to any given file at a time. This is exactly the same concern that would apply to multiple processes on a single non-containerized machine sharing a filesystem.
Comparison to bind mounts for the same purpose
docker run -v /host/shared/path:/app/data container-a
docker run -v /host/shared/path:/app/data container-b
The same sharing pattern also works with a bind mount instead of a named volume — both containers reference the identical host path. But this reintroduces the portability tradeoffs covered in the volumes-vs-bind-mounts question, since it's tied to a specific host path existing with correct permissions. Named volumes remain the more portable default even for this multi-container-sharing use case, for the same reasons they're generally preferred for single-container persistent storage.
Shared volumes are the right tool specifically for genuinely related containers cooperating on the same data. They are not a general-purpose way to pass data between unrelated services, which should communicate over the network instead (see the networking topic), rather than through a shared filesystem.