两类挂载是什么
Docker 把宿主数据带进容器有两种主流方式:命名卷(volume)由守护进程创建和管理,落在宿主的数据目录下,容器之间可以复用同一份数据;绑定挂载(bind)直接把宿主上一个已存在的路径映射进容器,路径写法完全由你决定。卷的初始化更友好:目标目录在镜像里有内容时会先复制进去;绑定挂载则原样使用宿主目录,宿主是空的,容器里也是空的。
基本信息
| 卷语法 | -v 卷名:容器路径 或 --mount type=volume,source=卷名,target=路径 |
|---|---|
| 绑定语法 | -v /宿主路径:容器路径 或 --mount type=bind,source=/宿主路径,target=路径 |
| 卷宿主位置 | Linux 下 /var/lib/docker/volumes/卷名/_data |
| 创建时机 | 卷不存在会自动创建;绑定源不存在时 -v 会创建空目录、--mount 直接报错 |
| 权限影响 | 卷默认继承镜像目录属主;绑定目录属主要与容器内 UID 对齐 |
| 适用平台 | Linux 原生;Windows/macOS 上卷在虚拟机内部,绑定需经共享层 |
怎么选
- 数据要备要迁、要跨主机重建:选卷,备份时用临时容器打包即可
- 要与宿主工具链协作(编辑器改配置、日志采集器抓文件):选绑定挂载
- 数据库类负载:选卷,避免宿主 I/O 与权限差异带来的不稳定
- 配置文件只读注入:绑定挂载加只读,改动即时生效不用重建镜像
- 容器间共享数据:卷更直观,命名后多个容器挂同一个名字
- Windows/macOS 开发环境跑数据库:选卷,绑定挂载在这一层性能与权限行为都更绕
两种写法与验证
两种写法与验证
# 命名卷:容器首次启动时把镜像里该目录的初始内容复制进卷
docker run -d --name pg -v pgdata:/var/lib/postgresql/data postgres:16-alpine
# 绑定挂载:宿主目录必须已存在且权限对齐,否则容器内写入失败
docker run -d -v /srv/app/config:/etc/app:ro app/web:1.0
# 结构化写法更明确,源目录不存在会直接报错而不是悄悄建空目录
docker run -d --mount type=bind,source=/srv/logs,target=/var/log/app app/web:1.0
# 核对卷落在哪、容器实际挂了什么
docker volume inspect pgdata
docker inspect -f '{{json .Mounts}}' pg六个维度对比
| 维度 | 命名卷 | 绑定挂载 |
|---|---|---|
| 管理方 | Docker 守护进程 | 宿主文件系统 |
| 宿主可见性 | Linux 在数据目录下,需 root 查看 | 任意路径,随手可及 |
| 初始化行为 | 空卷自动复制镜像目录内容 | 不复制,直接用宿主内容 |
| 跨平台一致性 | 较稳定 | Windows/macOS 有共享层差异 |
| 备份方式 | 临时容器打包或直接访问 Mountpoint | 宿主直接 tar/rsync |
| 典型用途 | 数据库、持久化业务数据 | 配置、代码、日志采集 |
清理规则不同:删容器时匿名卷会成为悬空卷留在磁盘上,而绑定挂载里的数据只受宿主目录影响。定期 docker volume ls --filter dangling=true 巡检可以避免磁盘被悄悄吃满。
把数据库数据目录放在绑定挂载上,若宿主备份工具按文件逐个抓取,容易在写入过程中产生不一致拷贝;卷配合停机或数据库自身备份机制更可靠。