Docker 数据卷与存储机制(持久化与共享实战)

前言

一、为什么需要数据卷

二、数据卷的类型

三、匿名卷(自动创建)

四、具名卷(命名卷)

[五、绑定挂载(Bind Mount)](#五、绑定挂载(Bind Mount))

[5.1 权限控制](#5.1 权限控制)

[5.2 容器到宿主机复制数据](#5.2 容器到宿主机复制数据)

[六、数据卷容器(Volumes From)](#六、数据卷容器(Volumes From))

[七、Volume 常用命令](#七、Volume 常用命令)

[八、Docker Compose 中的数据卷](#八、Docker Compose 中的数据卷)

九、持久化数据库案例

[9.1 MySQL 数据卷示例](#9.1 MySQL 数据卷示例)

[9.2 Redis 数据卷示例](#9.2 Redis 数据卷示例)

十、数据卷备份与恢复

[10.1 备份卷](#10.1 备份卷)

[10.2 恢复卷](#10.2 恢复卷)

十一、容器数据持久化设计建议

十二、卷清理与维护

十三、总结

前言

在前几篇中,我们学习了容器的运行、网络和资源控制。 但是------容器是临时性的:当你删除一个容器时,它内部的文件和数据也会随之消失。

在实际生产环境中,我们需要让:

  • 应用数据 能够长期保存;

  • 配置文件 能够方便修改;

  • 容器之间 能共享数据;

这些需求的核心就是:👉 Docker 数据卷(Volume)机制。


一、为什么需要数据卷

默认情况下,Docker 容器的数据保存在容器层(UnionFS)中:

  • 当容器删除时,数据随之销毁。

  • 容器与宿主机之间的数据无法直接交互。

解决方案: 使用 数据卷(Volume),即宿主机与容器之间的共享目录。

💡 一句话理解: 数据卷是"容器的硬盘映射",用来实现数据持久化与共享。


二、数据卷的类型

类型 挂载方式 特点
匿名卷 -v /data 仅容器内部路径,Docker 自动分配宿主机目录
具名卷 -v volume_name:/data 有自定义名称,方便复用
绑定挂载(Bind Mount) -v /host/path:/container/path 宿主机与容器共享目录
只读挂载 -v /data:/data:ro 宿主机数据只读不可写

三、匿名卷(自动创建)

复制代码
docker run -d -v /data nginx

查看卷:

复制代码
docker volume ls

查看卷详情:

复制代码
docker volume inspect <volume_name>

输出示例:

复制代码
"Mountpoint": "/var/lib/docker/volumes/1a2b3c4d/_data"

✅ 特点: Docker 自动分配目录,适用于临时或测试环境。


四、具名卷(命名卷)

复制代码
docker run -d --name web1 -v nginx_data:/usr/share/nginx/html nginx

查看卷:

复制代码
docker volume ls

输出:

复制代码
DRIVER    VOLUME NAME
local     nginx_data

宿主机路径:

复制代码
/var/lib/docker/volumes/nginx_data/_data

💡 适合场景: 生产环境中应用数据或配置文件的长期存储。


五、绑定挂载(Bind Mount)

直接将宿主机目录挂载到容器中。

复制代码
docker run -d \
  --name web2 \
  -v /opt/wwwroot:/usr/share/nginx/html \
  -p 8080:80 \
  nginx

测试修改内容:

复制代码
echo "Hello Docker Volume" > /opt/wwwroot/index.html

浏览器访问:

复制代码
http://宿主机IP:8080

✅ 页面会即时更新,不需要重启容器。


5.1 权限控制

只读挂载:

复制代码
docker run -d -v /opt/config:/etc/nginx/conf.d:ro nginx

:ro 表示容器内部无法修改该目录内容。 适合挂载配置文件、防止误改。


5.2 容器到宿主机复制数据

从容器中拷贝文件到宿主机:

复制代码
docker cp web1:/usr/share/nginx/html/index.html /tmp/

反向拷贝:

复制代码
docker cp /tmp/test.conf web1:/etc/nginx/conf.d/

六、数据卷容器(Volumes From)

多个容器之间共享数据卷。

创建共享卷容器:

复制代码
docker run -d --name dbdata -v /data/mysql mysql:5.7

使用相同卷的容器:

复制代码
docker run -d --name db1 --volumes-from dbdata mysql:5.7
docker run -d --name db2 --volumes-from dbdata mysql:5.7

此时 db1 与 db2 均共享 /data/mysql 数据。

💡 即使删除 dbdata 容器,卷也不会被删除,数据仍然保留。


七、Volume 常用命令

操作 命令 说明
查看所有卷 docker volume ls 显示卷列表
查看卷信息 docker volume inspect 卷名 查看路径与挂载点
删除卷 docker volume rm 卷名 删除指定卷
删除所有未使用卷 docker volume prune 清理无主卷
创建卷 docker volume create 卷名 手动创建卷

八、Docker Compose 中的数据卷

Compose 支持更简洁的卷定义方式。

复制代码
version: "3"
services:
  nginx:
    image: nginx
    ports:
      - "8080:80"
    volumes:
      - ./www:/usr/share/nginx/html
      - nginx_conf:/etc/nginx/conf.d
volumes:
  nginx_conf:

✅ 说明:

  • ./www:/usr/share/nginx/html → 绑定挂载(宿主机目录)

  • nginx_conf → 命名卷(自动管理)

查看卷列表:

复制代码
docker volume ls

九、持久化数据库案例

9.1 MySQL 数据卷示例

复制代码
docker run -d \
  --name mysql \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -v /opt/mysql_data:/var/lib/mysql \
  mysql:5.7

所有数据库文件都会存放在宿主机 /opt/mysql_data。


9.2 Redis 数据卷示例

复制代码
docker run -d \
  --name redis \
  -v /opt/redis_data:/data \
  redis:latest

容器删除后重新启动,数据仍会保留。


十、数据卷备份与恢复

10.1 备份卷

复制代码
docker run --rm \
  -v nginx_data:/data \
  -v $(pwd):/backup \
  busybox tar cvf /backup/backup.tar /data

10.2 恢复卷

复制代码
docker run --rm \
  -v nginx_data:/data \
  -v $(pwd):/backup \
  busybox tar xvf /backup/backup.tar -C /

💡 busybox 容器是轻量级工具镜像,非常适合卷备份操作。


十一、容器数据持久化设计建议

设计原则 说明
应用与数据分离 应用逻辑放在镜像中,数据放在卷中
使用具名卷管理数据 避免路径混乱,方便迁移
数据库一定要持久化 防止容器删除导致数据丢失
重要配置挂载为只读 防止意外修改生产配置
备份卷数据 使用 tar + volume 定期备份

十二、卷清理与维护

查看未使用卷:

复制代码
docker volume ls -f dangling=true

清理未使用卷:

复制代码
docker volume prune

清理所有无用资源(包括卷、镜像、容器):

复制代码
docker system prune -a

⚠️ 注意:清理操作不可逆,请谨慎执行。


十三、总结

通过本篇学习,你应掌握:

✅ 区分匿名卷、具名卷与绑定挂载

✅ 熟悉 -v 参数语法与权限设置

✅ 使用 --volumes-from 实现容器间共享数据

✅ 数据卷的备份与恢复方法

✅ Docker Compose 中的数据卷定义

✅ 构建安全、高可维护的持久化存储方案

相关推荐
穷人小水滴9 小时前
用容器编译 VirtualBox 虚拟机软件 (ArchLinux, podman)
linux·容器·virtualbox
EatFans9 小时前
Docker 实战部署:从本地镜像到云服务器,一篇走通 FastAPI + Celery + MySQL + Redis + Nginx
docker·fastapi
judezh10 小时前
api 容器一直 unhealthy?我把一个 Agent 运行时的健康检查逐条拆了,查出四个问题
运维·docker
暗不需求10 小时前
Docker 入门:从「光盘与 DVD」到全栈项目容器化实战
docker·容器·面试
春天花会开13110 小时前
内网 HTTPS 部署实战:私有 CA + Nginx 反向代理全流程复盘
运维·nginx·https
AllFiles10 小时前
K8s Node Exporter 异常 Write 超时排查实录
运维·后端·kubernetes
探索云原生10 小时前
一个 Deployment 就能跑 vLLM,为什么还需要 KServe?
docker·ai·云原生·kubernetes·go
虎头金猫6 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
分布式存储与RustFS6 天前
MinIO 官方 Docker 镜像被移除:依赖它的项目该怎么办
docker·云原生·devops·对象存储·minio·分布式存储
AI职业加油站6 天前
AI智能体应用工程师证书:政策红利下的职业新风口
大数据·运维·人工智能·学习·职场发展