尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Docker 命名卷与绑定挂载详解:到底该用哪个?

Docker 命名卷与绑定挂载详解:到底该用哪个?
📅 发布时间:2026/6/23 12:44:56

目录

① 导读卡片

② 背景与目标

容器数据为什么需要持久化?

不理解这个问题的后果

学完你能做什么?

③ 概念与原理

3.1 什么是卷(Volume)?

3.2 Docker 的两种卷类型

3.3 Docker Compose 是如何区分两者的?

④ 逻辑与对比

命名卷 vs 绑定挂载,最全对比

命名卷的完整关系图

⑤ 核心详解

5.1 命名卷(Named Volume)深入

怎么创建命名卷?

命名卷的数据藏在哪?

命名卷的生命周期管理

5.2 绑定挂载(Bind Mount)深入

绑定挂载的权限问题

5.3 命名卷的高级配置

5.4 多命名卷实战

⑥ 案例实战

实战一:Jenkins 数据持久化(命名卷 vs 绑定挂载的对比)

实战二:开发环境热加载(绑定挂载典型场景)

实战三:查看数据位置(排错技巧)

⑦ 避坑 & 最佳实践

常见坑点


① 导读卡片

一句话定位:Docker 数据持久化的两种核心方式——命名卷(Named Volume)和绑定挂载(Bind Mount)到底有什么区别、怎么选、怎么用,一文讲透。

  • 适合人群:刚入门 Docker,被volumes写法搞晕的开发者

  • 难度:⭐⭐☆☆☆

  • 阅读时长:12 分钟

  • 前置知识:知道docker run和docker-compose.yml基本语法


② 背景与目标

容器数据为什么需要持久化?

Docker 容器的文件系统是临时性的——容器被删除后,里面产生的所有数据都会丢失。这对以下场景是灾难性的:

  • 数据库数据(PostgreSQL、MySQL 的数据文件)

  • 应用配置(Jenkins、GitLab 的配置)

  • 日志文件(访问日志、错误日志)

为了解决这个问题,Docker 提供了卷(Volume)机制:把容器内的某个目录映射到宿主机上,容器删了,数据还在。

不理解这个问题的后果

你在看教程时一定会遇到两种写法:

version: '3.8' services: jenkins: volumes: - jenkins_home:/var/jenkins_home # 写法 A - /var/lib/jenkins:/var/jenkins_home # 写法 B

两种写法看上去差不多,但背后的行为完全不同。不理解它们的区别,会导致:

  • 找不到数据存在哪里

  • 权限问题反复报错

  • 教程里说得对但你运行结果不对

学完你能做什么?

  • ✅ 一眼分辨命名卷和绑定挂载

  • ✅ 知道数据实际存在宿主机的哪个位置

  • ✅ 根据场景选择正确的持久化方式

  • ✅ 彻底理解为什么有的文件需要sudo才能访问

  • ✅ 在一个docker-compose.yml里灵活混用两种卷


③ 概念与原理

3.1 什么是卷(Volume)?

卷= 容器内目录与宿主机目录之间的映射桥梁。

3.2 Docker 的两种卷类型

Docker 提供两种卷,区别只在于谁来指定宿主机上的路径:

类型宿主路径由谁指定语法特征
命名卷(Named Volume)Docker名字开头,不带/
绑定挂载(Bind Mount)用户以/、./、../开头

3.3 Docker Compose 是如何区分两者的?

这是 Docker Compose 的语法规则,写死了:

volumes: - jenkins_home:/var/jenkins_home # ✅ 命名卷(名字不带 /) - /var/lib/jenkins:/var/jenkins_home # ✅ 绑定挂载(/ 开头) - ./data:/app/data # ✅ 绑定挂载(./ 开头) - ../shared:/shared # ✅ 绑定挂载(../ 开头) - myproject_jenkins_home:/data # ✅ 命名卷(下划线不算路径分隔符)

判定规则极简:

左侧内容以/或./或../开头→ 绑定挂载 左侧内容不是以上述开头→ 命名卷

这就是你写jenkins_home:/var/jenkins_home时,Docker 把它当作卷名的原因。


④ 逻辑与对比

命名卷 vs 绑定挂载,最全对比

维度命名卷(Named Volume)绑定挂载(Bind Mount)
语法卷名:容器路径/宿主机路径:容器路径
数据存放/var/lib/docker/volumes/卷名/_data/你指定的路径
创建方式Docker 自动创建需手动确保路径存在
权限Docker 管理,需sudo宿主机当前用户权限
备份需要知道系统路径路径明确,直接备份
共享性多容器可共享多容器可共享
便携性需导出/导入卷直接拷贝目录
适用场景数据库、生产环境开发调试、配置文件注入

命名卷的完整关系图

Docker 引擎 │ ├── 卷管理 │ ├── vol_jenkins_home → 数据在 /var/lib/docker/volumes/vol_jenkins_home/_data/ │ ├── vol_postgres_data → 数据在 /var/lib/docker/volumes/vol_postgres_data/_data/ │ └── vol_redis_data → 数据在 /var/lib/docker/volumes/vol_redis_data/_data/ │ ├── 容器 A(挂载 vol_jenkins_home、vol_redis_data) ├── 容器 B(挂载 vol_jenkins_home) └── 容器 C(挂载 vol_postgres_data)

核心特点:

  • 一个命名卷可被多个容器同时挂载

  • 一个容器可挂载多个命名卷

  • 卷的生命周期独立于容器——容器删了,卷还在

  • Docker 可以管理任意数量的命名卷,没有上限


⑤ 核心详解

5.1 命名卷(Named Volume)深入

怎么创建命名卷?

方式一:docker volume create独立创建

docker volume create my_custom_volume # 查看卷列表 docker volume ls # 查看卷详情(可以看到真实路径) docker volume inspect my_custom_volume

输出示例:

[ { "CreatedAt": "2024-01-15T10:00:00Z", "Driver": "local", "Mountpoint": "/var/lib/docker/volumes/my_custom_volume/_data", "Name": "my_custom_volume", "Options": null, "Scope": "local" } ]

方式二:docker run -v时自动创建

docker run -v my_data:/app/data alpine # Docker 检查到 my_data 卷不存在,自动创建

方式三:docker-compose.yml 中自动创建

services: jenkins: volumes: - jenkins_home:/var/jenkins_home ​ volumes: # 显式声明(推荐) jenkins_home:
命名卷的数据藏在哪?
# 默认路径 /var/lib/docker/volumes/<项目名>_<卷名>/_data/ # 例如:项目文件夹叫 jenkins,卷名 jenkins_home # 实际位置:/var/lib/docker/volumes/jenkins_jenkins_home/_data/

⚠️ 注意:这个路径默认只有root可读。如果你直接用普通用户去访问会报Permission denied。

解决办法:

# 方式一:用 sudo sudo ls /var/lib/docker/volumes/jenkins_jenkins_home/_data/ # 方式二:改用绑定挂载(推荐调试用) # 把数据丢到自己用户目录下
命名卷的生命周期管理
# 列出所有卷 docker volume ls # 删除卷(卷必须不被任何容器使用) docker volume rm my_custom_volume # 删除所有未被使用的卷 docker volume prune # 备份卷(方法:临时容器打包) docker run --rm -v my_data:/source -v $(pwd):/backup alpine tar czf /backup/my_data_backup.tar.gz -C /source .

5.2 绑定挂载(Bind Mount)深入

绑定挂载的关键好处是路径由你掌控:

services: nginx: volumes: # 挂载单个配置文件 - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro # 挂载整个目录(开发时热加载) - ./html:/usr/share/nginx/html # 挂载日志目录 - ./logs:/var/log/nginx

ro标志:挂载为只读,防止容器内修改配置文件。

绑定挂载的权限问题
# ❌ 可能出错:宿主目录不存在 volumes: - /my/custom/path:/app # 如果 /my/custom/path 不存在,Docker 会创建它(但可能权限不对) # ✅ 安全做法:先创建目录 mkdir -p /home/user/jenkins_data chown -R 1000:1000 /home/user/jenkins_data # Jenkins 容器以 UID 1000 运行

5.3 命名卷的高级配置

在docker-compose.yml的顶级volumes中,你可以做更多配置:

volumes: # 基本声明 basic_volume: # 使用外部已存在的卷(不由 Compose 管理生命周期) external_volume: external: true # 指定卷驱动(如 NFS、云存储驱动) nfs_volume: driver: local driver_opts: type: nfs o: addr=192.168.1.100,rw device: ":/path/to/nfs/share" # 给卷加标签 labeled_volume: labels: environment: production backup: daily

外部卷(external: true)的应用场景:

# 场景:多个 Compose 项目共享同一个数据库卷 # 先用 docker volume create 创建 # docker volume create shared_postgres_data services: postgres: image: postgres:14 volumes: - shared_postgres_data:/var/lib/postgresql/data volumes: shared_postgres_data: external: true # 不创建新卷,使用已存在的

5.4 多命名卷实战

一个docker-compose.yml里可以写任意多个命名卷:

version: '3.8' services: jenkins: image: jenkins/jenkins:lts volumes: - jenkins_home:/var/jenkins_home - jenkins_logs:/var/log/jenkins postgres: image: postgres:14 volumes: - postgres_data:/var/lib/postgresql/data - postgres_backup:/backup redis: image: redis:7-alpine volumes: - redis_data:/data volumes: # 所有命名卷在此声明 jenkins_home: jenkins_logs: postgres_data: postgres_backup: redis_data:

即使不在顶级volumes中声明,Compose 也会隐式创建卷。但显式声明是好习惯,尤其是:

  • 你需要在多个服务间共享卷

  • 你需要设置外部卷或驱动选项

  • 你想让docker compose down -v可预测地删除卷


⑥ 案例实战

实战一:Jenkins 数据持久化(命名卷 vs 绑定挂载的对比)

命名卷写法:

version: '3.8' services: jenkins: image: jenkins/jenkins:lts privileged: true user: root ports: - "8080:8080" volumes: - jenkins_home:/var/jenkins_home - /var/run/docker.sock:/var/run/docker.sock volumes: jenkins_home:

数据位置:/var/lib/docker/volumes/<项目名>_jenkins_home/_data/

绑定挂载写法:

version: '3.8' services: jenkins: image: jenkins/jenkins:lts privileged: true user: root ports: - "8080:8080" volumes: - /opt/jenkins_data:/var/jenkins_home - /var/run/docker.sock:/var/run/docker.sock

数据位置:/opt/jenkins_data/(你可以随时访问)

权限修复(绑定挂载常见问题):

# Jenkins 容器内进程以 UID 1000 运行 # 如果宿主机目录权限不对,会报 Permission denied sudo chown -R 1000:1000 /opt/jenkins_data

实战二:开发环境热加载(绑定挂载典型场景)

version: '3.8' services: frontend: image: node:18 working_dir: /app command: npm run dev volumes: - ./frontend:/app # 绑定挂载:代码修改立即同步到容器 - /app/node_modules # 匿名卷:保护容器内 npm 安装的模块 backend: build: ./backend volumes: - ./backend:/app # 绑定挂载:热加载 - /app/node_modules # 匿名卷保护 environment: - NODE_ENV=development

关键技巧说明:

volumes: - ./backend:/app # 宿主机项目的 ./backend 覆盖容器 /app - /app/node_modules # 注意:这个没有宿主机路径

第二行- /app/node_modules的作用是:

  1. 宿主机目录./backend先挂载到容器/app

  2. Docker 创建了一个匿名卷,挂载到/app/node_modules

  3. 由于更具体的挂载点优先,/app/node_modules使用的是容器内原有的node_modules(包含 npm 安装的包)

  4. 宿主机上可能没有node_modules,避免了空目录覆盖导致模块丢失

实战三:查看数据位置(排错技巧)

# 1. 找到命名卷的实际路径 docker volume inspect myproject_db_data # → Mountpoint: /var/lib/docker/volumes/myproject_db_data/_data/ # 2. 查看容器使用的挂载 docker inspect my_container | grep -A 10 Mounts # 3. 绑定挂载的数据路径 # 直接去你指定的路径看就好了

相关新闻

  • Codex 国内下载安装教程:搭配 CC Switch 接入国产deepseek大模型,无需折腾配置
  • 破解汉绣商务礼品急单采购痛点:3CS方法论如何实现高效交付? - 资讯快报
  • 抚州南城县黄金回收避坑指南:套路拆解+本地三大靠谱品牌全攻略 - 衡金阁

最新新闻

  • 法奥钟表零件自动组装,微米级精密对位,保障走时准确性
  • 收藏!AI大模型前端进阶指南:从效率提升到产品落地
  • LineX荣登欧洲权威机器视觉期刊《inspect》
  • 从“归档凭证“到“数据资产“——合同智能应用实战思考
  • 高考后大学4年花10万,室内设计培训1个月花几千——算完这笔账我沉默了
  • VulnHub 靶机实战:Infosec_Warrior1 从信息收集到 Root 提权全流程

日新闻

  • Arduino-ESP32项目深度解析:解锁隐藏芯片支持与架构演进
  • 2026年 系统窗厂家/品牌推荐榜单:隔音系统窗+高端系统门窗的核心优势与选购指南 - 品牌发掘
  • NVBench:首个双语非言语发声语音合成评测基准详解与实践

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号