Docker Volume
A Docker volume is a special storage mechanism that Docker uses to persist data generated or used by containers.
Think of it like an external hard drive for your containers — even if the container is deleted, the data in the volume can remain.
Why use volumes?
Persistence → Keeps data even after the container stops or is removed.
Sharing → Multiple containers can read/write to the same volume.
Isolation from container lifecycle → Updating or replacing a container won’t delete your data.
Better performance → On many systems, volumes are faster than writing to the container’s filesystem.
Docker Network
A Docker network is how containers communicate with each other, with your host machine, and with the outside world.
its like virtual LAN cables or Wi-Fi inside Docker — they connect containers so they can share data.
This happens because, Containers are isolated by default.
- Networks let containers:
-Talk to each other by name (not just IP).
Control what is connected to what.
Separate environments (e.g., dev, test, prod)
Types of Docker Networks
- Bridge (default) Used when you run containers without specifying a network.
Containers on the same bridge network can talk to each other using container names.
Host
Removes the network isolation, container shares the host’s network stack.
Good for performance or if you need the container to listen on the host’s network directly.None
No network access at all
Totally isolated — used for security.Overlay (Swarm / multi-host)
Used in Docker Swarm or Kubernetes.
Allows containers on different hosts to communicate securely.
1 — Prepare the project (compose: app + db)
Create a directory and files:
mkdir -p ~/docker-day19 && cd ~/docker-day19
Create docker-compose.yml
(paste exactly):
services:
db:
image: postgres:15
environment:
POSTGRES_USER: devuser
POSTGRES_PASSWORD: devpass
POSTGRES_DB: devdb
volumes:
- db-data:/var/lib/postgresql/data
networks:
- app-net
web:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./site:/usr/share/nginx/html:ro
depends_on:
- db
networks:
- app-net
volumes:
db-data:
networks:
app-net:
Create a simple web page folder for nginx:
mkdir site
echo "<h1>Hello from Docker Compose (Day 19)</h1>" > site/index.html
Notes:
-
db-data
is a named volume that stores Postgres data outside the container. -
./site
is a bind mount (local folder) mapped into nginx so you can see a page onhttp://localhost:8080
.
2 — Start the stack (detached)
docker-compose up -d
Check status:
docker-compose ps
Open browser: http://localhost:8080
→ you should see the HTML message.
3 — Inspect services, logs, and network
View logs (all services):
docker-compose logs # or specific: docker-compose logs db
Inspect the db container data dir listing:
docker-compose exec db ls -la /var/lib/postgresql/data
List Docker networks and find the Compose network (named <folder>_app-net
or similar):
docker network ls
# inspect the compose network (replace name with actual):
docker network inspect <network_name>
To see containers on that network:
docker network inspect <network_name> --format '{{json .Containers}}' | jq
4 — Scaling the service (replicas)
You can scale the web service (run multiple nginx containers behind the same network/port mapping IPs will be on different ephemeral container ports — note host port conflict if mapping same port; scaling with host port mapping is limited, but Compose can create multiple replicas for testing):
docker-compose up -d --scale web=3
Check them:
docker-compose ps
docker ps | grep nginx
To return scale to 1:
docker-compose up -d --scale web=1
Note: For production-grade scaling consider Docker Swarm/Kubernetes. Compose
--scale
works for local development.
5 — Bring the stack down and remove associated volumes/networks
Stop and remove containers, networks (also remove volumes created by compose):
docker-compose down --volumes
--volumes
deletes the db-data
volume created by the compose file. Omit --volumes
if you want to keep the DB data.
6 — Task 2: Share a named volume between independent containers (hands-on)
This is the simplest way to prove two containers can share data.
Create a named volume:
docker volume create shared-vol
Start a writer container that mounts it and keeps running:
docker run -d --name writer --mount source=shared-vol,target=/data busybox sh -c "sleep 3600"
Write a file inside the volume (inside writer):
docker exec writer sh -c "echo 'hello from writer' > /data/hello.txt"
docker exec writer sh -c "ls -la /data && cat /data/hello.txt"
Start a reader container that mounts the same volume and read the file:
docker run --rm --name reader --mount source=shared-vol,target=/data busybox cat /data/hello.txt
You should see: hello from writer
You can also exec into a second long-running container:
docker run -d --name reader2 --mount source=shared-vol,target=/data busybox sh -c "sleep 3600"
docker exec reader2 sh -c "cat /data/hello.txt"
7 — Inspect volumes and clean up
List volumes:
docker volume ls
Inspect a volume (see mountpoint on host):
docker volume inspect shared-vol
Remove containers and the volume when done:
docker rm -f writer reader2 # reader was run with --rm so it may already be gone
docker volume rm shared-vol
If you used db-data
with compose and want to remove it:
docker volume ls
docker volume rm <db-data-volume-name>
8 — Quick troubleshooting tips
- If a
COPY
in Dockerfile fails, ensure the files exist in the build context (same folder you rundocker build
from). - If
docker-compose
complains about versions, removeversion:
or use the latest compose syntax. - If ports conflict, choose a different host port (e.g.
8081:80
). -
docker-compose down --volumes
removes named volumes created by compose. Be careful — this deletes DB data.