Docker volumes and bind mounts both provide persistent storage for containers, but they differ in management, performance, and portability — and the network mode you choose (bridge, host, or none) determines how containers communicate. This article explains the practical differences, when to use each mount type, and how to configure networks in a Docker Compose file.
Background: Why Mounts and Networks Matter
When a container stops or is removed, its writable layer is deleted unless you use a volume or bind mount. Volumes are managed by Docker and stored in a dedicated directory on the host (/var/lib/docker/volumes/ on Linux), while bind mounts map any host directory into the container. Networks, on the other hand, control how containers talk to each other and to the outside world. Compose lets you define both mounts and networks declaratively, so your stack is reproducible and easy to share.
How Docker Volumes Work
Volumes are the recommended way to persist data in Docker. You create a volume with docker volume create or let Compose create it automatically when you define it under volumes:. The volume is mounted at a path in the container, and Docker handles the underlying storage. Volumes are easy to back up, move between containers, and share across multiple containers. They also work on remote hosts and can be encrypted or replicated by third-party plugins.
In a Compose file, a volume mount looks like this:
services:
db:
image: postgres
volumes:
- db-data:/var/lib/postgresql/data
volumes:
db-data:
Here db-data is a named volume. Docker creates it on the first run and reuses it on subsequent runs, so your data survives container recreation.
How Bind Mounts Work
Bind mounts are a direct mapping from a host path to a container path. You specify the host path and the container path separated by a colon, like ./html:/usr/share/nginx/html. Bind mounts are ideal for development because you can edit files on your host and see changes instantly in the container. They are also useful for passing configuration files or sockets (e.g., the Docker socket).
However, bind mounts depend on the host’s directory structure, so they are less portable than volumes. If you move a Compose file to another machine, the host paths may not exist. Also, bind mounts can expose sensitive host directories if misconfigured.
Choosing Between Volume and Bind Mount
Use a named volume when:
- You need persistent data that should be managed by Docker (backup, restore, migration).
- You want the data to be portable across hosts and environments.
- You are running in production or on a remote server.
Use a bind mount when:
- You are developing and want live-reload of code or config files.
- You need to share files between the host and container that are not part of the image.
- You want to use tools on the host to inspect or edit the files.
A common misconception is that volumes are slower than bind mounts. In practice, on Linux, both use the same underlying filesystem, and performance differences are negligible for most applications. The real trade-offs are management and portability.
Networking in Docker Compose
Compose creates a default network for your services, allowing them to resolve each other by service name. For example, if you have a web service and a db service, web can connect to db using the hostname db on the default network. This is the simplest and most common setup.
You can also define custom networks in Compose:
services:
web:
image: nginx
networks:
- frontend
db:
image: postgres
networks:
- backend
networks:
frontend:
backend:
This isolates traffic: web can only reach db if they share a network. In the example above, they don’t, so web cannot connect to db. You would need to add db to the frontend network or put both on the same network.
Common Network Modes and When to Use Them
Beyond custom networks, Compose supports several network modes:
- bridge (default): Containers get their own IP and communicate via a virtual bridge. Good for most multi-container apps.
- host: The container shares the host’s network stack. Use when you need performance or specific ports, but it reduces isolation.
- none: No network. Use for offline tasks or security.
To set a network mode in Compose, use network_mode: host or network_mode: none. Note that when using host, you cannot link containers by service name — you must use localhost or the host’s IP.
Common Problems and Misconceptions
One frequent issue is forgetting to declare a volume in the top-level volumes: section. If you only list it under the service, Compose will create an anonymous volume each time, leading to data loss when you run docker compose down. Always declare named volumes explicitly.
Another problem is using relative paths in bind mounts. Compose resolves relative paths from the directory containing the Compose file, so ./data is relative to that file. If you move the file, the path changes. Use absolute paths or environment variables for clarity.
For networks, a common mistake is assuming that services on different custom networks can talk to each other. They cannot unless you attach them to the same network. Also, when you use network_mode: host, the ports mapping is ignored — the container uses the host’s ports directly, which can cause conflicts.
Frequently Asked Questions
Can I use both a volume and a bind mount for the same container?
Yes, you can specify multiple mounts in the volumes: list. For example, you might use a named volume for database data and a bind mount for configuration files. Each mount is independent and goes to a different container path.
Does the network type affect volume performance?
No, network type and volume type are independent. Volumes store data on disk, and the network handles container-to-container traffic. Performance of a volume depends on the underlying storage, not the network mode.
How do I back up a named volume?
You can run a temporary container that mounts the volume and creates a tar archive. For example: docker run --rm -v myvolume:/data -v $(pwd):/backup alpine tar czf /backup/backup.tar.gz -C /data . This copies the volume contents to the host.
Why does my bind mount show empty files inside the container?
If the host directory is empty, the container sees an empty directory, even if the image has files at that path. Bind mounts override the image’s content. To avoid this, copy the files to the host directory first or use a named volume and copy files on first run.
Can I change a service’s network after it’s created?
You can connect a running container to an additional network with docker network connect, but in Compose, you typically edit the file and run docker compose up -d to recreate the service with the new network configuration.
What’s the difference between ports and expose in Compose?
ports maps a host port to a container port, making the service accessible from outside. expose only makes the port available to other containers on the same network — it does not publish it to the host. Use expose for internal communication and ports for external access.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Mac Start Up Automatically After Power Failure?
- Expose Self-Hosted Service Securely Without Cloudflare Tunnel
- Nano Delivery for Functional Foods: What It Can and Can’t Do4.00
- Disable Apple Watch Turn-by-Turn Vibration While Driving
- Convert Play FLAC in iTunes: Full Guide
- Soda Foundation Charter: What It Means