docker-compose
volumes_from
compose version 3
container volumes
docker tutorial

docker-compose volumes_from equivalent with version 3

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In Compose file version 3, the old volumes_from pattern is usually replaced by mounting the same named volume, bind mount, or read-only config path into each service explicitly. The important change is that volume sharing is now described directly in each service rather than inherited from another container.

What volumes_from Used to Do

Older Compose files could say "mount whatever volumes this other container uses." That worked, but it also hid important storage details behind another service definition.

Version 3 pushes you toward a clearer pattern: define the shared volume once and mount it wherever it is needed.

Named Volume Equivalent

Here is the most common replacement. Instead of inheriting volumes from another service, both services mount the same named volume:

yaml
1version: "3.9"
2
3services:
4  app:
5    image: nginx:alpine
6    volumes:
7      - shared-data:/usr/share/nginx/html
8
9  worker:
10    image: alpine
11    command: ["sh", "-c", "ls -la /data && sleep 3600"]
12    volumes:
13      - shared-data:/data
14
15volumes:
16  shared-data:

That is the normal version-3 equivalent. The volume is declared once and attached explicitly to both services.

Bind Mount Equivalent

If the data lives on the host machine rather than in a Docker-managed named volume, use the same bind mount on both services:

yaml
1version: "3.9"
2
3services:
4  app:
5    image: nginx:alpine
6    volumes:
7      - ./data:/usr/share/nginx/html
8
9  worker:
10    image: alpine
11    command: ["sh", "-c", "ls -la /data && sleep 3600"]
12    volumes:
13      - ./data:/data

This is often the right choice for local development when you want live file edits from the host.

Read-Only Sharing

If one container should only consume the shared data, make its mount read-only:

yaml
1services:
2  reader:
3    image: alpine
4    command: ["sh", "-c", "cat /data/example.txt && sleep 3600"]
5    volumes:
6      - shared-data:/data:ro

That makes the intent explicit and is usually better than the old implicit inheritance model.

Why This Is Better

The version-3 style is more verbose, but it is also clearer:

  • each service shows exactly what it mounts
  • there is less hidden coupling between containers
  • named volumes can be reused without a "data-only container" pattern

In practice, this means the old volumes_from workflow is mostly unnecessary.

Migrating an Old Compose File

If you are upgrading from an old file, the migration is usually:

  1. identify the actual shared volume paths
  2. define named volumes at the top level if needed
  3. mount those same volumes in each service explicitly

That is the direct conceptual replacement.

Service Coupling Becomes More Visible

One advantage of the newer style is that storage dependencies are obvious in code review. You no longer have to inspect another container to discover where a service gets its data. That visibility usually makes Compose files easier to maintain as the application grows.

Common Pitfalls

The biggest mistake is looking for a one-line version-3 keyword that behaves exactly like volumes_from. The replacement is structural, not syntactic.

Another mistake is recreating a data-only container just to mimic the old pattern. In most cases, a named volume is simpler and more maintainable.

Developers also forget to distinguish between named volumes and bind mounts. Named volumes are managed by Docker, while bind mounts point to a host path.

Finally, be careful with write access. If multiple services mount the same volume read-write, the application must be designed for concurrent access.

Summary

  • Compose version 3 generally replaces volumes_from with explicit shared volume mounts.
  • Mount the same named volume in each service that needs the data.
  • Use bind mounts when the shared content should come from the host filesystem.
  • Prefer explicit read-only mounts where appropriate.
  • The modern pattern is clearer and usually removes the need for data-only containers.

Course illustration
Course illustration

All Rights Reserved.