Learn how containers communicate with each other and how to keep data alive even after containers are removed.
Modern applications rarely run as a single container. A typical application might include a web application, a database, a cache layer, and background workers. For these services to work together, containers need a reliable way to communicate and share data.
In this article, we'll learn:
- How Docker networking works
- How containers discover each other
- Docker network drivers
- Persistent storage with Docker volumes
- Essential networking and volume commands
- A real-world multi-container example
By the end, we'll understand two of the most important concepts in Docker: networking and data persistence.
Why Docker Networking Matters
Every container runs inside its own isolated network namespace.
This isolation improves security and prevents conflicts, but it also creates an important challenge:
If containers are isolated, how does a web application connect to a database?
Imagine a web application running inside one container and MongoDB running inside another. Without networking, they cannot communicate.
Docker solves this problem using Docker Networks.
A Docker network allows containers to communicate with each other while remaining isolated from unrelated containers.
Web App Container
|
v
Docker Network
|
v
Database Container
Without a shared network, containers cannot easily find or communicate with each other.
Docker Network Drivers
Docker supports several network drivers, but most developers primarily use three.
Bridge Network
A bridge network creates a private virtual network on the Docker host.
Containers connected to the same bridge network can communicate with each other securely.
Create a custom bridge network:
docker network create my-app-network
Benefits of bridge networks:
- Container-to-container communication
- Isolation from other applications
- Built-in DNS resolution
- Easy management
For most Docker projects, a user-defined bridge network is the recommended choice.
Host Network
With the host driver, the container shares the host machine's network stack directly.
docker run --network host nginx
Advantages:
- Slightly better networking performance
- No port mapping required
Disadvantages:
- Reduced isolation
- Potential port conflicts
- Less flexibility
For most applications, bridge networks are the better option.
None Network
The none driver completely disables networking.
docker run --network none alpine
A container using this driver:
- Cannot access the internet
- Cannot communicate with other containers
- Cannot accept incoming connections
This is useful for highly restricted workloads that require no network access.
The Most Important Feature: Service Discovery
One of Docker's most powerful networking features is built-in DNS resolution.
Instead of connecting containers by IP address, we can connect them using container names.
The Problem with IP Addresses
Container IP addresses are assigned dynamically.
If a container restarts, its IP address can change.
Hardcoding IP addresses creates fragile configurations that eventually break.
For example:
192.168.1.25 → MongoDB
If MongoDB restarts and receives a new IP address, the application can no longer connect.
The Better Approach
Create a custom network:
docker network create my-app-network
Run MongoDB:
docker run -d \
--name mongo \
--network my-app-network \
mongo
Run Mongo Express:
docker run -d \
--name mongo-express \
--network my-app-network \
-e ME_CONFIG_MONGODB_SERVER=mongo \
-p 8081:8081 \
mongo-express
Notice this environment variable:
ME_CONFIG_MONGODB_SERVER=mongo
Mongo Express connects to MongoDB using the container name.
Docker automatically resolves:
mongo → container IP address
This feature is called service discovery.
Instead of relying on changing IP addresses, containers communicate using stable names.
Essential Docker Network Commands
List all networks:
docker network ls
Create a network:
docker network create my-app-network
Inspect a network:
docker network inspect my-app-network
Connect a running container:
docker network connect my-app-network my-container
Disconnect a container:
docker network disconnect my-app-network my-container
Remove a network:
docker network rm my-app-network
These commands are the foundation of Docker networking and are frequently used when troubleshooting multi-container applications.
Why Docker Volumes Matter
Containers are designed to be disposable.
If a container is removed, any data stored inside its writable layer is lost forever.
For applications such as databases, this is a major problem.
Imagine storing customer information in MongoDB and then deleting the container.
Without persistent storage:
Container removed = Data lost
This is where Docker Volumes become essential.
Docker Volumes allow data to exist independently from containers.
Even if a container is removed and recreated, the data remains intact.
Types of Docker Storage
Docker provides multiple ways to persist data.
Named Volumes
Named volumes are the recommended approach for most production workloads.
Create a volume:
docker volume create mongo-data
Use the volume:
docker run -d \
--name mongo \
-v mongo-data:/data/db \
mongo
Benefits:
- Managed by Docker
- Portable across environments
- Easy backups and maintenance
- Cleaner configuration
For databases and production applications, named volumes are usually the best choice.
Bind Mounts
Bind mounts connect a specific host directory to a container.
Example:
docker run -d \
-v /home/user/data:/data/db \
mongo
Benefits:
- Direct access to files from the host
- Great for development workflows
- Easy editing of source code
Drawbacks:
- Depends on host filesystem paths
- Less portable
- Can introduce permission issues
Bind mounts are commonly used during development, while named volumes are preferred for production workloads.
Understanding Volume Mapping
Volume syntax follows this format:
-v source:destination
Example:
-v mongo-data:/data/db
mongo-data → Host side
/data/db → Container side
If the container writes data to /data/db, that data is stored in the Docker volume named mongo-data.
This is similar to Docker port mapping:
-p 8080:80
8080 → Host port
80 → Container port
The same "host-to-container" concept applies to both networking and storage.
Essential Docker Volume Commands
List all volumes:
docker volume ls
Create a volume:
docker volume create my-volume
Inspect a volume:
docker volume inspect my-volume
Remove a volume:
docker volume rm my-volume
Remove unused volumes:
docker volume prune
⚠️ Use docker volume prune carefully.
It permanently deletes unused volumes and can remove important data if executed without checking first.
A good habit is to review existing volumes before deleting anything.
Building a Real Multi-Container Application
Let's combine networking and volumes into a realistic example.
Step 1: Create a Network
docker network create my-app-network
Step 2: Create a Volume
docker volume create mongo-data
Step 3: Start MongoDB
docker run -d \
--name mongo \
--network my-app-network \
-v mongo-data:/data/db \
mongo
Step 4: Start Mongo Express
docker run -d \
--name mongo-express \
--network my-app-network \
-e ME_CONFIG_MONGODB_SERVER=mongo \
-p 8081:8081 \
mongo-express
What happens here?
- MongoDB stores its data in a persistent volume.
- Mongo Express shares the same Docker network.
- Mongo Express discovers MongoDB using the hostname
mongo. - Data survives container recreation.
- Both services remain isolated from unrelated containers.
This is a real-world pattern used in countless Docker applications.
How Networking and Volumes Work Together
A successful containerized application usually needs both networking and persistence.
Networking provides:
- Communication between services
- Service discovery
- Isolation between applications
Volumes provide:
- Persistent storage
- Data durability
- Independence from container lifecycle
Without networking, services cannot communicate.
Without volumes, important data disappears when containers are removed.
Together, they form the foundation of modern containerized applications.
Final Thoughts
Running a single container is useful, but real-world applications require much more.
A web application needs to communicate with databases, caches, and supporting services. At the same time, important data must survive container restarts, updates, and redeployments.
Docker Networks solve communication challenges through service discovery and isolation.
Docker Volumes solve persistence challenges by separating data from container lifecycles.
These two concepts are fundamental building blocks for everything that comes next:
- Docker Compose
- CI/CD pipelines
- Kubernetes
- Cloud-native applications
Master Docker networking and volumes, and we'll be well prepared to build and operate real-world containerized applications.
Top comments (0)