ToolkitX
知识库工具箱

Docker 数据持久化

volume, bind mount 数据管理

15min·进阶

01. 为什么需要数据持久化

容器是无状态的——删掉容器,里面的数据也跟着没了。这跟容器设计的哲学有关:容器应该是用完就丢的。但数据库、上传的文件、配置文件这些数据需要活过容器的生命周期,所以需要持久化。 Docker 提供两种持久化方式:Volume(由 Docker 管理的存储卷)和 Bind Mount(把宿主机目录直接映射进容器)。 Volume 是推荐方式——由 Docker 统一管理,可以跨容器共享、备份、迁移。Bind Mount 更简单直接但依赖宿主机目录结构,换个机器可能就挂了。 还有个 tmpfs Mount——数据存内存里不落盘,容器停了数据就没了,适合存临时敏感数据。
bash
# 创建 volume
docker volume create mydata

# 查看所有 volume
docker volume ls

# 查看 volume 详情
docker volume inspect mydata

# 使用 volume
docker run -d -v mydata:/var/lib/mysql --name db mysql

# 删 volume(确认没容器在用)
docker volume rm mydata

02. Volume 用法详解

Volume 是最推荐的持久化方案,Docker 帮你管文件存在哪(默认在 /var/lib/docker/volumes/ 下)。 匿名 Volume——docker run -v /data 不指定名字,Docker 自动生成一个随机名字的 volume。删容器时如果不加 -v 参数,匿名 volume 不会被删(会堆积垃圾)。 具名 Volume——docker run -v mydata:/data 指定一个名字。跨容器共享同一个 volume 很容易:两个容器都用 -v mydata:/data。 Volume 的备份和迁移:可以用一个临时容器挂载 volume,然后 tar 打包导出。或者用 docker volume 的子命令备份到远程(这需要第三方工具配合,原生 Docker 没有)。
bash
# 具名 volume
docker run -d -v dbdata:/var/lib/mysql mysql

# 多个容器共享同一个 volume
docker run -d -v shared:/data --name app1 alpine
docker run -d -v shared:/data --name app2 alpine

# 备份 volume
docker run --rm -v dbdata:/data -v $(pwd):/backup alpine \
  tar czf /backup/dbdata.tar.gz /data
docker run -v 后面第一个参数如果不带斜杠就是 volume 名字,带了斜杠 Docker 认为是宿主机路径(Bind Mount)。

03. Bind Mount 用法

Bind Mount 直接把宿主机的一个目录或文件映射进容器。容器里对那个目录的读写直接反映到宿主机上,反之亦然。开发环境特别好用——本地改代码,容器里实时生效。 跟 Volume 的区别:Bind Mount 你指定路径(如 /home/user/project:/app),Volume 由 Docker 管理路径。Bind Mount 更灵活但可移植性差,换台机器路径可能变了。 常见场景:开发环境挂载源代码(改代码容器自动更新)、挂载配置文件(nginx.conf)、挂载宿主机 socket(比如 docker.sock)。
bash
# Bind Mount
docker run -d -v $(pwd)/html:/usr/share/nginx/html nginx

# 只读挂载
docker run -d -v $(pwd)/config:/etc/nginx:ro nginx

# 挂载单个文件
docker run -d -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro nginx

# docker-compose 里
# volumes:
#   - ./html:/usr/share/nginx/html
#   - ./config:/etc/nginx:ro
挂载文件而非目录时,文件必须在宿主机上已存在。Docker 不会自动创建文件,如果不存在 Docker 会把它当成目录名创建空目录。

04. tmpfs 与内存存储

tmpfs Mount 把数据存内存里,不写磁盘。容器停了数据就没了。适合的场景:临时缓存、敏感信息(不希望落在磁盘上)、需要极速 IO 的数据。 tmpfs 跟 Volume 和 Bind Mount 不同——它不是持久化的,容器删了就没了。 使用方式:docker run --tmpfs /tmp 或者 docker run --mount type=tmpfs,destination=/tmp,tmpfs-size=64M。注意限一下大小,别把宿主机内存吃光了。
bash
# tmpfs
docker run --tmpfs /tmp:rw,size=64M nginx

# --mount 语法(更明确)
docker run --mount type=tmpfs,destination=/tmp,tmpfs-size=64M nginx

# docker-compose 里
# tmpfs:
#   - /tmp:size=64M

05. Volume 驱动与最佳实践

Docker 的 Volume 支持插件驱动,可以把数据存到远程存储:NFS、云盘(AWS EBS、Azure Disk)、分布式存储(Ceph、GlusterFS)。这对有状态容器(数据库)特别重要——容器挂了换台机器,挂载同一个远程 volume,数据还在。 最佳实践: 1. 数据库、消息队列等有状态服务必须用 Volume 2. 开发环境用 Bind Mount,生产环境用 Volume 3. Volume 定期备份,尤其是数据库的 Volume 4. 清理不再用的 volume:docker volume prune 5. 不要在 container 里存重要的数据,所有需要持久化的都挂载出来
bash
# 清理未使用的 volume
docker volume prune

# 查看 volume 占用空间
docker system df -v

# 使用 NFS volume 驱动
docker volume create \
  --driver local \
  --opt type=nfs \
  --opt o=addr=192.168.1.100,rw \
  --opt device=:/path/to/share \
  nfs-volume
docker volume prune 会删掉所有没被容器使用的 volume。删之前确认没有重要的数据还在里面。

知识测验

1/5正确 0

Volume 和 Bind Mount 最大区别?

下一节

Docker 安全

下一节