Managing Data with Docker Volumes
One challenge when working with Docker containers is data persistence. Containers are ephemeral, meaning any data created within a container is lost when the container is removed. Docker volumes solve this problem by providing a way to persist data outside of containers.
Understanding Docker Volumes
Docker volumes are the preferred mechanism for persisting data generated by and used by Docker containers. They are completely managed by Docker and are isolated from the host filesystem's directory structure.
Benefits of using volumes include:
- Volumes are easier to back up or migrate than bind mounts
- You can manage volumes using Docker CLI commands
- Volumes work on both Linux and Windows containers
- Volumes can be more safely shared among multiple containers
- Volume drivers let you store volumes on remote hosts, cloud providers, or encrypt the contents of volumes
Creating and Using Docker Volumes
Let's create a simple MySQL database container that uses a volume to persist its data.
Creating a Volume
First, create a Docker volume:
docker volume create mysql-data
You can list all volumes with:
docker volume ls
You should see your new volume in the list:
DRIVER VOLUME NAME
local mysql-data
Running a Container with a Volume
Now, let's run a MySQL container that uses this volume:
docker run --name mysql-db -e MYSQL_ROOT_PASSWORD=mysecretpassword -v mysql-data:/var/lib/mysql -p 3306:3306 -d mysql:5.7
This command:
--name mysql-db
: Names the container "mysql-db"
-e MYSQL_ROOT_PASSWORD=mysecretpassword
: Sets an environment variable to configure MySQL
-v mysql-data:/var/lib/mysql
: Mounts the "mysql-data" volume to the directory where MySQL stores its data
-p 3306:3306
: Maps port 3306 on the host to port 3306 in the container
-d
: Runs the container in detached mode
mysql:5.7
: Specifies the image to use
Wait a moment for the container to start up, then check that it's running:
docker ps
Interacting with the Database
Let's create a database and a table to demonstrate data persistence. First, connect to the MySQL container:
docker exec -it mysql-db bash
Inside the container, connect to the MySQL server:
mysql -u root -pmysecretpassword
Create a new database and table:
CREATE DATABASE testdb;
USE testdb;
CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255));
INSERT INTO users (name) VALUES ('John'), ('Jane'), ('Bob');
SELECT * FROM users;
You should see the inserted data:
+----+------+
| id | name |
+----+------+
| 1 | John |
| 2 | Jane |
| 3 | Bob |
+----+------+
Exit the MySQL prompt and the container:
exit
exit
Testing Volume Persistence
Now, let's stop and remove the container, then create a new one using the same volume:
docker stop mysql-db
docker rm mysql-db
Create a new container using the same volume:
docker run --name mysql-db-new -e MYSQL_ROOT_PASSWORD=mysecretpassword -v mysql-data:/var/lib/mysql -p 3306:3306 -d mysql:5.7
Now connect to the new container and check if our data persisted:
docker exec -it mysql-db-new bash
mysql -u root -pmysecretpassword
USE testdb
SELECT * FROM users
You should see the same data we inserted earlier:
+----+------+
| id | name |
+----+------+
| 1 | John |
| 2 | Jane |
| 3 | Bob |
+----+------+
Exit the MySQL prompt and the container:
exit
exit
This demonstrates that the data persisted even after the original container was removed, because it was stored in a Docker volume.
Inspecting and Managing Volumes
You can inspect a volume to get more information about it:
docker volume inspect mysql-data
This will show details like the mount point and driver used:
[
{
"CreatedAt": "YYYY-MM-DDTHH:MM:SS+00:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/mysql-data/_data",
"Name": "mysql-data",
"Options": {},
"Scope": "local"
}
]
To clean up, let's stop and remove the container:
docker stop mysql-db-new
docker rm mysql-db-new
If you want to remove the volume as well:
docker volume rm mysql-data
You've now learned how to use Docker volumes to persist data between container lifecycles, which is essential for stateful applications like databases.