
Docker volumes are a persistent storage mechanism that decouples your data from the container lifecycle. Volumes let containers retain data across restarts and removals, and allow multiple containers to share a common data source. Unlike bind mounts, Docker manages volumes internally and stores them under /var/lib/docker/volumes/
on Linux systems.
This article shows how to create and inspect Docker volumes, interact with their contents, and use them in Docker Compose workflows. You'll also learn how to back up and restore volume data, and how to reference volumes using the VOLUME
instruction in a Dockerfile.
The Short Answer Version
The following Docker commands demonstrate how to manage persistent data using volumes:
# Create a new volume
$ docker volume create web_content
# Run a container and mount the volume
$ docker container run -d -v web_content:/app/data --name volume_demo httpd
# List all volumes
$ docker volume ls
# Inspect a volume
$ docker volume inspect web_content
# Remove a volume
$ docker volume rm web_content
# Remove all unused volumes
$ docker volume prune
When to Use Docker Volumes
Use Docker volumes instead of bind mounts in the following situations:
- You want data to persist across container restarts or removals.
- You need consistent storage behavior across Linux, macOS, and Windows.
- You prefer Docker-managed storage lifecycle and internal volume handling.
- You plan to back up or restore application data regularly.
- You need to share persistent data between multiple containers.
Bind mounts are more suitable for development environments where code changes on the host need to reflect immediately in the container. For production environments, Docker volumes are the preferred choice due to their portability, safety, and lifecycle integration.
Manually Create and Link Volumes
Docker volumes allow you to persist container data independently of the container lifecycle. This section demonstrates how to manually create a volume, attach it to a container, inspect it, and remove both the container and the volume.
Create a Docker volume.
console$ docker volume create web_content
This command creates a Docker-managed volume named
web_content
. Docker stores it internally and tracks its metadata.volume create
: Initializes a new volume.web_content
: The name assigned to the volume.
Output:
web_content
Run a container and mount the volume.
console$ docker container run -d -v web_content:/usr/local/apache2/htdocs --name apache_with_volume httpd
This launches a container with the
httpd
image and mounts the named volume at the web server's root, making it available for data persistence.-d
: Runs the container in detached mode.-v web_content:/usr/local/apache2/htdocs
: Mounts theweb_content
volume to Apache’s web root.--name apache_with_volume
: Assigns a custom name to the container.httpd
: Uses the official Apache HTTP server image.
Output:
03d0120e51dd822148d4c4c0464473cdad8a916e22ba5685ec495e47573dc722
List all volumes.
console$ docker volume ls
This command verifies that the volume was created and is currently available.
volume ls
: Lists all volumes managed by Docker.
Output:
DRIVER VOLUME NAME local web_content
Inspect the volume.
console$ docker volume inspect web_content
Use this command to confirm the volume’s internal mount path and attributes, useful for debugging and manual access.
volume inspect
: Displays low-level metadata about a volume.web_content
: Target volume name.
Output:
[ { "CreatedAt": "2025-06-06T17:38:52Z", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/web_content/_data", "Name": "web_content", "Options": null, "Scope": "local" } ]
List all containers.
console$ docker container ls -a
This confirms that the container is active and correctly linked to the volume.
container ls -a
: Shows all containers, running or stopped.
Output:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 03d0120e51dd httpd "httpd-foreground" 46 seconds ago Up 45 seconds 80/tcp apache_with_volume
Check volume usage by container.
console$ docker container inspect --format={{.Mounts}} apache_with_volume
This shows where the volume is mounted inside the container, validating its usage path.
inspect
: Retrieves metadata about the container.--format={{.Mounts}}
: Filters output to show mount points.
Output:
[{volume web_content /var/lib/docker/volumes/web_content/_data /usr/local/apache2/htdocs local z true }]
Stop the container.
console$ docker container stop apache_with_volume
This halts the container without removing it, preserving the volume and data.
container stop
: Gracefully stops a running container.
Output:
apache_with_volume
Remove the container.
console$ docker container rm apache_with_volume
This removes the container while leaving the named volume intact for reuse.
container rm
: Deletes the stopped container.
Output:
apache_with_volume
Remove the volume.
console$ docker volume rm web_content
This permanently removes the volume and its contents.
volume rm
: Deletes the specified volume.
Output:
web_content
Use Volumes in Dockerfiles
While Dockerfiles can't create named volumes, they can define mount points expected at runtime using the VOLUME
instruction. Docker automatically creates an anonymous volume for such paths unless you explicitly mount a named one when running the container.
Navigate to the user's home directory and create a
docker
directory.console$ cd ~ $ mkdir docker
Navigate into the new directory.
console$ cd docker/
Create a Dockerfile.
console$ nano Dockerfile
Add the following content to the Dockerfile:
dockerfileFROM httpd VOLUME ["/usr/local/apache2/htdocs"] CMD ["httpd-foreground"]
Save and close the file.
This Dockerfile builds an Apache-based image that treats
/usr/local/apache2/htdocs
as a volume path.VOLUME ["/usr/local/apache2/htdocs"]
: Declares a runtime mount point for persistent data.
Build the image.
console$ docker image build -t apache_with_volume .
This builds the Dockerfile and creates a new image named
apache_with_volume
.-t apache_with_volume
: Tags the resulting image with a readable name.
Output:
[+] Building 0.1s (5/5) FINISHED docker:default => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 110B 0.0s => [internal] load metadata for docker.io/library/httpd 0.0s => => writing image sha256:c886f948f696b... 0.0s => => naming to docker.io/library/apache_with_volume 0.0s
Run the container.
console$ docker container run -d --rm apache_with_volume
-d
: Runs the container in detached mode.--rm
: Automatically removes the container when it exits.
Docker automatically creates an anonymous volume and mounts it at
/usr/local/apache2/htdocs
, as defined in the Dockerfile.To use a named volume instead of an anonymous one, pass the
-v
flag explicitly:console$ docker container run -d --rm -v web_content:/usr/local/apache2/htdocs apache_with_volume
This allows you to control the volume lifecycle while still benefiting from Dockerfile-defined mount points.
Interact with Docker Volumes
Docker does not let you directly mount volumes on the host system, but you can access and modify volume contents from within a running container.
Start a container with the volume mounted.
console$ docker container run -d --name apache_with_volume -v web_content:/usr/local/apache2/htdocs httpd
This launches the container and mounts the named volume to serve persistent content.
-d
: Runs the container in detached mode.--name apache_with_volume
: Assigns a custom name to the container.-v web_content:/usr/local/apache2/htdocs
: Mounts the volume to Apache’s default web root.httpd
: Uses the official Apache image.
Output:
03d0120e51dd8221...
Create an HTML file on your host machine.
console$ echo "<h1>Hello Apache from docker volume</h1>" > index.html
This creates a simple HTML file for demonstration.
Copy the file into the container.
console$ docker cp index.html apache_with_volume:/usr/local/apache2/htdocs/
This places your HTML file into the volume's mount point within the container.
docker cp
: Copies files between host and container.index.html
: Source file on the host.apache_with_volume:/usr/local/apache2/htdocs/
: Destination path inside the container.
Output:
Successfully copied 2.05kB to apache_with_volume:/usr/local/apache2/htdocs/
View file contents inside the container.
console$ docker exec apache_with_volume \ cat /usr/local/apache2/htdocs/index.html
This verifies that the file was successfully copied into the container.
docker exec
: Runs a command inside a running container.cat /usr/local/apache2/htdocs/index.html
: Prints the contents of the copied file.
Output:
<h1>Hello Apache from docker volume</h1>
Back up the volume from inside the container.
console$ docker exec apache_with_volume \ tar czf /usr/local/apache2/htdocs/httpd_backup.tar.gz -C /usr/local/apache2/htdocs .
This creates a backup archive of the volume’s contents inside the container.
tar czf
: Creates a compressed.tar.gz
archive.-C /usr/local/apache2/htdocs .
: Archives the current directory (volume contents) intohttpd_backup.tar.gz
.
Copy the backup file from the container to the host.
console$ docker cp apache_with_volume:/usr/local/apache2/htdocs/httpd_backup.tar.gz .
This allows you to save a local backup of the volume.
docker cp
: Transfers files from the container to the host.apache_with_volume:/usr/local/apache2/htdocs/httpd_backup.tar.gz
: Source archive inside the container..
: Destination path on the host (current directory).
Output:
Successfully copied 2.05kB to /home/john/docker/.
Restore the volume by copying the archive back and extracting it.
console$ docker cp httpd_backup.tar.gz apache_with_volume:/usr/local/apache2/htdocs/
console$ docker exec apache_with_volume \ tar xzf /usr/local/apache2/htdocs/httpd_backup.tar.gz -C /usr/local/apache2/htdocs
These steps restore the previous data state into the mounted volume.
- First command copies the backup archive into the container.
- Second command extracts the archive contents into the volume directory.
Use Volumes with Docker Compose
Docker Compose supports named volumes natively. These volumes are automatically created and managed alongside the service lifecycle.
Create a
docker-compose
directory in your home path.console$ cd ~ $ mkdir docker-compose
Navigate to the new directory.
console$ cd docker-compose/
Create a
docker-compose.yml
manifest.console$ nano docker-compose.yml
Add the following YAML content to the file:
yamlservices: web: image: httpd volumes: - web_content:/usr/local/apache2/htdocs volumes: web_content:
This configuration tells Docker Compose to create a volume named
web_content
and mount it to the container at/usr/local/apache2/htdocs
.image: httpd
: Uses the official Apache image.volumes:
: Mounts the named volumeweb_content
to Apache's web root.- The
volumes:
section at the root defines the named volume.
Start the service.
console$ docker compose up -d
This command builds and runs the container while automatically creating the declared volume and network.
up -d
: Starts the services defined in the Compose file in detached mode.
Output:
[+] Running 3/3 ✔ Network docker-compose_default Created 0.2s ✔ Volume "docker-compose_web_content" Created 0.0s ✔ Container docker-compose-web-1 Started 0.6s
Inspect the volume created by Docker Compose.
console$ docker volume inspect docker-compose_web_content
Replace
docker-compose_web_content
with the name of your Docker Compose volume. This confirms that the named volume declared in the Compose file was created and is mounted as expected.volume inspect
: Displays detailed metadata about the named volume.
Output:
[ { "Name": "docker-compose_web_content", "Mountpoint": "/var/lib/docker/volumes/docker-compose_web_content/_data", ... } ]
Shut down the service and remove the volume.
console$ docker compose down -v
This removes all Docker resources tied to the Compose application, including the named volume.
down
: Stops and removes containers, networks, and volumes.-v
: Ensures that named volumes declared in the Compose file are also deleted.
Output:
[+] Running 3/3 ✔ Container docker-compose-web-1 Removed 1.3s ✔ Network docker-compose_default Removed 0.2s ✔ Volume docker-compose_web_content Removed 0.0s
Conclusion
In this article, you explored how to create and manage Docker volumes using the CLI, Dockerfiles, and Docker Compose. You learned how to mount volumes to containers, inspect and remove them, and back up or restore volume data using practical workflows. Docker volumes are essential for separating application logic from persistent data. They improve data durability, simplify container management, and support scalable, production-ready deployments.
No comments yet.