How do you share data between multiple containers?

6 minintermediateshared-volumesmulti-container-patterns

Quick Answer

Mount the same named volume, or the same bind-mounted host path, into more than one container. A volume isn't exclusively owned by any single container, so any number of containers can mount and read/write the same data at once, as long as the application-level access pattern is safe for concurrent access. This is the standard way to share files between a main application container and a sidecar-style helper container — 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 — mounted read-only via :ro, since it should never need to modify the application's own logs. Neither container needs to know about the other. They're simply both pointed at the same underlying storage.

Why this is the standard technique for sidecar-style patterns

This is the same idea as the sidecar container pattern. A helper container — a log shipper, 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, mount the volume read-only with :ro. This stops that container from accidentally — or maliciously, if compromised — corrupting data another container depends on. It's least privilege applied 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 files. But Docker provides no automatic coordination, locking, or consistency beyond whatever the underlying filesystem gives you. If multiple containers might write to the same file concurrently, the applications themselves are responsible for handling that safely — file locking, using an actual database instead of raw files, or a design where only one container ever writes to a given file. This is the same concern that applies 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 works with a bind mount too — both containers reference the same host path. But this brings back the usual bind mount tradeoffs, since it depends on a specific host path existing with correct permissions. Named volumes stay the more portable default, even for this multi-container-sharing case, for the same reasons they're generally preferred for single-container persistent storage.

Shared volumes are the right tool for genuinely related containers cooperating on the same data. They're not a general-purpose way to pass data between unrelated services — those should communicate over the network instead.