Mastering Docker Volumes: Named vs. Anonymous & When to Use Each
Using Unnamed Volumes in Docker-Compose
Before diving into named volumes, let’s first see how an unnamed volume is created.
version: "3.6"
services:
web:
build: ./server/
volumes:
- ./server:/app
- ./server/node_modules:/app/node_modules
ports:
- "4000:4000"
depends_on:
- postgres
environment:
- NODE_ENV=development
postgres:
image: postgres:11
restart: always
ports:
- "5432:5432"
volumes:
- db_data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: postgres
Explanation
./server:/app
maps the/app
directory inside the container to the./server
directory on your host machine../server/node_modules:/app/node_modules
ensures that dependencies are kept in sync.
However, unnamed volumes can become difficult to manage, especially when working with multiple projects.
Why You Should Use Named Volumes
If you're handling multiple projects with Docker, your volumes can quickly become a mess:
docker volume ls
DRIVER VOLUME NAME
local 2f075f6a07ebb...
local reddit-clone_db_data
local reddit-clone_server
local postgres_db_vol
Named volumes make it easier to manage and delete specific volumes:
# With named volumes:
docker volume rm reddit-clone_server_node_modules
# Instead of trying to guess:
docker volume rm 2f075f6a07ebb...
Using Named Volumes in Docker-Compose
version: "3.6"
services:
postgres:
image: postgres:11
restart: always
ports:
- "5432:5432"
volumes:
- db_data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: postgres
volumes:
db_data:
In this case, /var/lib/postgresql/data
is mapped to a named volume db_data
.
Mapping a Named Volume to a Specific Filesystem Path
For development, you may want to bind the named volume to a specific directory on your host machine:
version: "3.6"
services:
web:
build: ./server/
volumes:
- server:/app
- server_node_modules:/app/node_modules
ports:
- "4000:4000"
depends_on:
- postgres
environment:
- NODE_ENV=development
postgres:
image: postgres:11
restart: always
ports:
- "5432:5432"
volumes:
- db_data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: postgres
volumes:
db_data:
server:
driver_opts:
type: none
device: ${PWD}/server
o: bind
server_node_modules:
driver_opts:
type: none
device: ${PWD}/server/node_modules
o: bind
Caveat: Named Volumes Are Not Auto-Deleted
Unlike anonymous volumes, named volumes persist even after running docker-compose rm -v
. You must delete them manually:
docker volume rm <volume_name>
When to Use Anonymous Volumes
node_modules
Issues
Mapping node_modules
from the host can cause problems:
- If the host system and Docker image use different OS versions, dependencies may break.
- The container’s
node_modules
can get hidden if the host directory is empty.
Using an anonymous volume can help:
services:
server:
build: ./server/
volumes:
- server:/app
- ./server/node_modules:/app/node_modules
volumes:
server:
driver_opts:
type: none
device: ${PWD}/server
o: bind
This ensures node_modules
persists inside the container without interference from the host.
Conclusion
Named volumes provide better organization and persistence, but anonymous volumes can be useful in some scenarios like handling node_modules
. Understanding when to use each can help you avoid common pitfalls in Docker development.