容器数据卷
Docker:将应用和环境打包成一个镜像
如果数据都在容器中,那么将容器删除,数据就会丢失,风险太高,所以需要将数据持久化。
例:
Mysql容器 → 删除 == 删库跑路!
所以要将Mysql数据可以存储在本地,这就需要容器之间有一个数据共享的技术,来将Docker容器中产生的数据同步到本地!
这就是卷技术!(目录的挂载,将我们容器内的目录,挂载到Linux上面)

image.png
卷技术:容器的持久化和同步操作!容器间也是可以数据共享的!
方式一:直接使用命令来挂载 -v
# 双向绑定
docker run -it -v 主机目录:容器内目录
# 启动centos容器 并将容器内/home与容器外linux的/home/ceshi目录进行同步操作
[root@liuyi home]# docker run -it -v /home/ceshi:/home centos /bin/bash
[root@d977f2605373 /]#
# 新开窗口 查看是否挂载成功
[root@liuyi home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d977f2605373 centos "/bin/bash" 16 minutes ago Up 16 minutes sad_feynman
[root@liuyi home]# docker inspect d977f2605373
结果内容很多,找到以下部分则是挂载成功:
"Mounts": [
{
"Type": "bind",
"Source": "/home/ceshi", # 宿主机目录
"Destination": "/home", # docker容器目录
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
# 测试 - 容器内/home下新建test.java
[root@d977f2605373 home]# ls
[root@d977f2605373 home]# touch test.java
[root@d977f2605373 home]# ls
test.java
[root@d977f2605373 home]#
# 测试 - 宿主机/home/ceshi/下查看 发现同步文件成功
[root@liuyi ceshi]# ls
test.java
[root@liuyi ceshi]#
* 同样的在宿主机/home/ceshi/目录下创建文件,也会同步至容器内/home目录下
* 编辑文件也是一样会同步,即使exit退出了容器,在宿主机/home/ceshi/目录下创建、删除文件,修改文件内容,在 docker start 容器id (docker ps -a 查询运行过的容器id) 启动容器之后查看容器内/home目录下的文件也被同步了操作
测试步骤:
1.停止容器
2.宿主机上修改文件
3.启动容器
4.容器内的数据依旧是同步的

a2cc87b6-ea64-4f43-be24-2e3d391617e0.png
容器数据卷优点:同步后只需求在宿主机上修改文件,容器内会自动同步,无需再进入容器修改。
安装MySQL
解决MySQL数据持久化问题
# 获取镜像
[root@liuyi home]# docker pull mysql:5.7
# 运行容器,需要做数据挂载 (注意:安装mysql时需要配置密码)
# 官方命令:docker run --name some-mysql -e MYSQL_ROOT_PASSWORD_FILE=/run/secrets/mysql-root -d mysql:tag
# -d 后台运行
# -p 端口映射(宿主机端口:容器端口)
# -v 卷挂载 (可以多个-v 挂载多个目录)
# -e 环境配置
# --name 容器名字
[root@liuyi home]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
# 连接测试
1.可以使用数据库工具连接测试
2.使用数据库工具创建新建一个数据库test_database
3.查看宿主机/home/mysql/data/目录下会多一个test_database文件
删除容器,但是映射到宿主机目录的文件不会受影响!!!
# 删除容器(彻底删除 docker ps 和 docker ps -a 都无法查到)
[root@liuyi home]# docker rm -f mysql01
mysql01
[root@liuyi home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@liuyi home]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
74e143012e3c tomcat "catalina.sh run" 47 hours ago Exited (143) 27 hours ago heuristic_leavitt
30ea50a45640 portainer/portainer "/portainer" 2 days ago Exited (2) 47 hours ago elastic_keller
d1fa45a53424 tomcat "catalina.sh run" 3 days ago Exited (143) 47 hours ago tomcat01
d0f8c656fcfb nginx "/docker-entrypoint.…" 3 days ago Exited (0) 3 days ago nginx01
95160a4accd1 centos "/bin/bash" 3 days ago Exited (0) 3 days ago dreamy_keller
f014391a9c38 hello-world "/hello" 4 days ago Exited (0) 4 days ago quizzical_goldwasser
[root@liuyi home]#
# 查看宿主机映射目录,发现挂载到本地的数据卷没有丢失,这就实现了容器数据持久化功能!
[root@liuyi /]# cd /home//mysql/
[root@liuyi mysql]# ls
conf data
[root@liuyi mysql]# cd data
[root@liuyi data]# ls
auto.cnf client-cert.pem ibdata1 ibtmp1 private_key.pem server-key.pem
ca-key.pem client-key.pem ib_logfile0 mysql public_key.pem sys
ca.pem ib_buffer_pool ib_logfile1 performance_schema server-cert.pem test_database
[root@liuyi data]#
具名挂载和匿名挂载
1、 匿名挂载(随机指定挂载目录,只写容器内路径,不写容器外路径)
-v 容器内路径
# -p 宿主机端口:容器内端口
# -P 随机分配端口 (大写的P)
[root@liuyi home]# docker run -d -P --name nginx01 -v /etc/nginx nginx
01fa63a5c003729500cde10d153b09e61cac3fe2f89192d7d8674db7c380a7f7
[root@liuyi home]# docker volume --help # 查看volume帮助文档
Usage: docker volume COMMAND
Manage volumes
Commands:
create Create a volume
inspect Display detailed information on one or more volumes
ls List volumes
prune Remove unused local volumes
rm Remove one or more volumes
Run 'docker volume COMMAND --help' for more information on a command.
[root@liuyi home]# docker volume ls # 查看的都是匿名挂载的卷
DRIVER VOLUME NAME
local 4eabcfb7cda6790a3882bb4345398dc01251dd03dab3a4be482fac977fa6272a
local 27e406fe83d635c6aafe1b1564e3608d523f81ecd9e105ef6599454d7ca06f88
[root@liuyi home]#
2、具名挂载
-v 卷名:容器内路径 (卷名前没有“/”)
注意:
-v juming-nginx:/etc/nginx 与 -v /juming-nginx:/etc/nginx 有“/”和没有“/”是不同的,
juming-nginx是给卷起了一个名字,
/juming-nginx是具体目录,没有会自动生成。
# 具名挂载
[root@liuyi home]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
0aa82586251bdb8a3652286bc07ed0d2e2caf8746e678c5fc5763438fc8524c6
[root@liuyi home]# docker volume ls
DRIVER VOLUME NAME
local 4eabcfb7cda6790a3882bb4345398dc01251dd03dab3a4be482fac977fa6272a # 卷名
local 27e406fe83d635c6aafe1b1564e3608d523f81ecd9e105ef6599454d7ca06f88 # 卷名
local juming-nginx # ********* 挂载时取的名字,这就是具名挂载 *********
[root@liuyi home]#
# 查看卷路径(docker volume inspect 卷名)
[root@liuyi home]# docker volume inspect juming-nginx
[
{
"CreatedAt": "2026-02-28T15:12:54+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data", # ********* 这就是卷的路径 *********
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]
[root@liuyi home]#
所有的docker容器内的卷,没有指定目录的情况下都是在“/var/lib/docker/volumes/卷名/_data”。(_data数据)
# docker的核心目录 工作目录
[root@liuyi home]# cd /var//lib/docker/
[root@liuyi docker]# ll
total 52
drwx--x--x 4 root root 4096 Feb 24 10:19 buildkit
drwx--x--- 14 root root 4096 Feb 28 15:12 containers # 容器
-rw------- 1 root root 36 Feb 24 10:19 engine-id
drwx------ 3 root root 4096 Feb 24 10:19 image # 镜像
drwxr-x--- 3 root root 4096 Feb 24 10:19 network # 网络配置
drwx--x--- 67 root root 12288 Feb 28 15:12 overlay2
drwx------ 4 root root 4096 Feb 24 10:19 plugins # 插件
drwx------ 2 root root 4096 Feb 24 10:57 runtimes
drwx------ 2 root root 4096 Feb 24 10:19 swarm
drwx------ 2 root root 4096 Feb 26 09:02 tmp
drwx-----x 5 root root 4096 Feb 28 15:12 volumes # 卷挂载
[root@liuyi docker]#
# 卷目录
[root@liuyi docker]# cd volumes/
[root@liuyi volumes]# ll
total 36
drwx-----x 3 root root 4096 Feb 26 09:02 27e406fe83d635c6aafe1b1564e3608d523f81ecd9e105ef6599454d7ca06f88
drwx-----x 3 root root 4096 Feb 28 14:58 4eabcfb7cda6790a3882bb4345398dc01251dd03dab3a4be482fac977fa6272a
brw------- 1 root root 253, 1 Feb 24 10:57 backingFsBlockDev
drwx-----x 3 root root 4096 Feb 28 15:12 juming-nginx
-rw------- 1 root root 32768 Feb 28 15:12 metadata.db
[root@liuyi volumes]# cd juming-nginx/
[root@liuyi juming-nginx]# ls
_data
[root@liuyi juming-nginx]# cd _data/
[root@liuyi _data]# ll
total 28
drwxr-xr-x 2 root root 4096 Feb 28 15:12 conf.d
-rw-r--r-- 1 root root 1007 Dec 28 2021 fastcgi_params
-rw-r--r-- 1 root root 5349 Dec 28 2021 mime.types
lrwxrwxrwx 1 root root 22 Dec 28 2021 modules -> /usr/lib/nginx/modules
-rw-r--r-- 1 root root 648 Dec 28 2021 nginx.conf # ****** nginx配置文件 ******
-rw-r--r-- 1 root root 636 Dec 28 2021 scgi_params
-rw-r--r-- 1 root root 664 Dec 28 2021 uwsgi_params
[root@liuyi _data]# cat nginx.conf # 查看
通过具名挂载可以方便的找到挂载的一个卷,大多数情况都是使用‘具名挂载’,不建议使用匿名挂载!
总结:
-v 容器内路径 # 匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v /宿主机路径:容器内路径 # 指定路径挂载
拓展
# 通过 -v 容器内路径:宿主机路径:ro rw 改变读写权限
ro # readonly 只读
rw # readwrite 可读可写
# 一旦设置了容器权限,容器对我们挂载出来的内容就有限定了!
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
# 只要看到 ro ,就说明这个路径的内容只能通过宿主机来操作,容器内部是无法操作的!
方式二:DockerFile 挂载
DockerFile就是用来构建 docker 镜像的构建文件!一个命令脚本!
通过这个脚本就可以生成镜像,镜像是一层一层的,每个命令都是一层!
# 在/home下创建一个docker-test-volume文件夹
[root@liuyi home]# mkdir docker-test-volume
[root@liuyi home]# ls
apps dist docker-test-volume liuyi.java project usr
[root@liuyi home]# cd docker-test-volume/
# 创建文件dockerfile1并写入命令 名字随机 内容里指令需要大写 (cat dockerfile1的结果就是写入的命令)
[root@liuyi docker-test-volume]# vim dockerfile1
[root@liuyi docker-test-volume]# cat dockerfile1
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "----end----"
CMD /bin/bash
# 执行构建镜像的命令
# 注意:命令最后有一个“.”,不可遗忘!!!
[root@liuyi docker-test-volume]# docker build -f /home/docker-test-volume/dockerfile1 -t liuyi/centos:1.0 .
[+] Building 0.2s (5/5) FINISHED docker:default
=> [internal] load build definition from dockerfile1 0.0s
=> => transferring dockerfile: 120B 0.0s
=> [internal] load metadata for docker.io/library/centos:latest 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [1/1] FROM docker.io/library/centos:latest 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:88a327c6cfeef6087c83f9cbfdf13f022fe72f5c346e9500b5932d19e9d2d522 0.0s
=> => naming to docker.io/liuyi/centos:1.0 0.0s
# 查看镜像
[root@liuyi docker-test-volume]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat02 1.0 9449b0c673c4 3 days ago 684MB
nginx latest 605c77e624dd 4 years ago 141MB
tomcat 9.0 b8e65a4d736d 4 years ago 680MB
mysql 5.7 c20987f18b13 4 years ago 448MB
hello-world latest feb5d9fea6a5 4 years ago 13.3kB
centos latest 5d0da3dc9764 4 years ago 231MB
liuyi/centos 1.0 88a327c6cfee 4 years ago 231MB # ****** 自己构建的镜像 ******
[root@liuyi docker-test-volume]#
# 启动静茹构建的镜像
[root@liuyi docker-test-volume]# docker run -it 88a327c6cfee /bin/bash
[root@56c29c81e6bb /]# ls -l
total 56
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 360 Mar 2 06:57 dev
drwxr-xr-x 1 root root 4096 Mar 2 06:57 etc
drwxr-xr-x 2 root root 4096 Nov 3 2020 home
lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
drwx------ 2 root root 4096 Sep 15 2021 lost+found
drwxr-xr-x 2 root root 4096 Nov 3 2020 media
drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt
drwxr-xr-x 2 root root 4096 Nov 3 2020 opt
dr-xr-xr-x 147 root root 0 Mar 2 06:57 proc
dr-xr-x--- 2 root root 4096 Sep 15 2021 root
drwxr-xr-x 11 root root 4096 Sep 15 2021 run
lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Nov 3 2020 srv
dr-xr-xr-x 13 root root 0 Mar 2 06:57 sys
drwxrwxrwt 7 root root 4096 Sep 15 2021 tmp
drwxr-xr-x 12 root root 4096 Sep 15 2021 usr
drwxr-xr-x 20 root root 4096 Sep 15 2021 var
drwxr-xr-x 2 root root 4096 Mar 2 06:57 volume01 # ****** 这个目录就是我们生成镜像的时候自动挂载的,数据卷目录(dockerfile1) ******
drwxr-xr-x 2 root root 4096 Mar 2 06:57 volume02 # ****** 这个目录就是我们生成镜像的时候自动挂载的,数据卷目录(dockerfile1) ******
[root@56c29c81e6bb /]#
dockerfile1文件中只写了容器内的目录["volume01","volume02"],所以这是一个匿名挂载,这个卷和外部一定有一个同步的目录!
# 进入volume01文件夹 创建 container.txt 文件
[root@56c29c81e6bb /]# cd volume01
[root@56c29c81e6bb volume01]# touch container.txt
[root@56c29c81e6bb volume01]# ls
container.txt
[root@56c29c81e6bb volume01]#
# 新开窗口(宿主机)
# docker inspect 查看镜像信息 (用CONTAINER ID查看)
[root@liuyi docker-test-volume]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
56c29c81e6bb 88a327c6cfee "/bin/bash" 20 minutes ago Up 20 minutes eager_khorana
0aa82586251b nginx "/docker-entrypoint.…" 2 days ago Up 2 days 0.0.0.0:32769->80/tcp, :::32769->80/tcp nginx02
01fa63a5c003 nginx "/docker-entrypoint.…" 2 days ago Up 2 days 0.0.0.0:32768->80/tcp, :::32768->80/tcp nginx01
[root@liuyi docker-test-volume]# docker inspect 56c29c81e6bb
# 结果很长 找到Mounts部分
"Mounts": [
{
"Type": "volume",
"Name": "12ae134e781e1d02f2259a6e6a8f9806ff0125924a6370ef7dac6502f1610aa3",
"Source": "/var/lib/docker/volumes/12ae134e781e1d02f2259a6e6a8f9806ff0125924a6370ef7dac6502f1610aa3/_data", # ****** 容器外目录 ******
"Destination": "volume01",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "a744b02a4aefc9830813321b8d4b3fdb774b81049f3225e06d2ad38ebb2baba2",
"Source": "/var/lib/docker/volumes/a744b02a4aefc9830813321b8d4b3fdb774b81049f3225e06d2ad38ebb2baba2/_data", # ****** 容器外目录 ******
"Destination": "volume02",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
# 查看在容器内创建的 container.txt 文件 已经同步过来了
[root@liuyi docker-test-volume]# cd /var/lib/docker/volumes/12ae134e781e1d02f2259a6e6a8f9806ff0125924a6370ef7dac6502f1610aa3/_data
[root@liuyi _data]# ls
container.txt
[root@liuyi _data]#
这种方式会经常使用,因为我们经常会构建自己的镜像!
如果构建镜像时没有挂载卷,就要手动镜像挂载 -v 卷名:容器内路径!