Docker 数据卷入门:volume 与 bind mount 怎么选
Docker 数据卷入门:volume 与 bind mount 怎么选
容器删了,数据还在吗?默认情况下不在。容器里的文件系统跟着容器走,容器一删,写进去的数据就没了。数据卷就是解决这个问题的:把数据存到容器外面,容器换了、升级了,数据还在。
Docker 挂数据主要有两种方式:volume 和 bind mount。看起来都是把宿主机目录挂进容器,实际用法和适用场景差别不小。
一、volume:交给 Docker 管
volume 是 Docker 自己管理的存储,数据放在 Docker 的数据目录里,由 Docker 负责创建、备份和删除:
docker volume create mydata
创建一个名为 mydata 的卷,再把它挂到容器里:
docker run -d -v mydata:/data nginx
容器里 /data 目录下写的东西,都会落到 mydata 这个卷上。容器删掉重建,只要重新挂同一个卷,数据就还在。
查看现有的卷:
docker volume ls
删掉不再用的卷:
docker volume rm mydata
也可以一次清理所有没被容器使用的卷:
docker volume prune
volume 最大的好处是省心:不用关心数据在宿主机哪个路径,备份、迁移都按卷名操作,换一台机器 docker volume 照样认得。数据库、缓存这类应用数据,用 volume 是最稳妥的选择。
二、bind mount:直接挂宿主机目录
bind mount 是把宿主机上某个具体目录直接挂进容器:
docker run -d -v /home/user/html:/usr/share/nginx/html nginx
这里宿主机的 /home/user/html 直接对应容器里的 /usr/share/nginx/html,改宿主机上的文件,容器里立刻就能看到。
这种方式适合开发场景:本地改代码、容器里直接跑,不用每次改完重新构建镜像。配置文件也是同理,把宿主机上的配置文件挂进容器,改配置重启容器即可生效。
但 bind mount 有两个要注意的地方。第一,路径写错不会报错,只会挂一个空目录进去,容器可能因此起不来或者行为异常,排查时先确认宿主机路径确实存在。第二,权限问题更常见:容器里的进程用户和宿主机文件属主不一致时,会出现写不进去的情况,先用 ls -l 对一下属主和权限。
三、两者怎么选
一句话:持久化数据用 volume,开发调试和配置文件用 bind mount。
- 数据库、消息队列、上传文件这类应用数据:用
volume,让 Docker 统一管理,备份和迁移都按卷名来 - 本地开发、热更新代码:用
bind mount,改完即生效 - 只读挂载配置文件:两种都可以,
bind mount更直观,记得加上只读标记:docker run -v /home/user/app.conf:/etc/app.conf:ro nginx - 临时数据:两种都不用,容器自带的读写层就够了,删容器时顺手清理
在 docker-compose.yml 里,两者的写法也很容易区分:
volumes:
- mydata:/data
这是 volume,需要在文件顶部声明 mydata。而下面这样就是 bind mount:
volumes:
- ./html:/usr/share/nginx/html
路径以 ./ 或 / 开头,Compose 会把它当作宿主机目录直接挂载。
四、新手容易踩的坑
- 容器删了数据还在,是因为卷还在;想彻底清掉数据要连卷一起删,
docker rm -v可以在删容器时顺带删掉它用的匿名卷 - 匿名卷没有名字,
docker volume ls里一堆长串 ID 的就是它们,用完记得清理,不然磁盘会被悄悄占满 bind mount挂一个不存在的宿主机目录,Docker 会自动建一个空目录,容易造成误会:容器里看到的是空目录,不是你以为的那个文件- 备份
volume最简单的方法是起一个临时容器把它打成包:docker run --rm -v mydata:/data -v /home/user/backup:/backup alpine tar czf /backup/mydata.tar.gz -C /data .
小结
volume 是 Docker 帮你管的"保险箱",适合长期保存的数据;bind mount 是宿主机目录的"直通门",适合开发时频繁改动的文件。分清这两者的用途,容器数据丢不丢、好不好备份,心里就有数了。
- 点赞
- 收藏
- 关注作者
评论(0)