当前位置: 首页 > news >正文

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

目录

① 导读卡片

② 背景与目标

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

不理解这个问题的后果

学完你能做什么?

③ 概念与原理

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 rundocker-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. 绑定挂载的数据路径 # 直接去你指定的路径看就好了

http://www.jsqmd.com/news/1035405/

相关文章:

  • Codex 国内下载安装教程:搭配 CC Switch 接入国产deepseek大模型,无需折腾配置
  • RimWorld模组管理终极指南:用RimSort高效管理上百个模组
  • SLM算法在OFDM系统上的PAPR抑制 — MATLAB仿真
  • 摄剪智变,启映未来|黎明奥杰摄影培训,打造AI影像实战新生态 - 猫头鹰AI推广
  • 破解汉绣商务礼品急单采购痛点:3CS方法论如何实现高效交付? - 资讯快报
  • 抚州南城县黄金回收避坑指南:套路拆解+本地三大靠谱品牌全攻略 - 衡金阁
  • 数字化知识产权管理落地案例:本地化部署的实践观察
  • 全网营销推广深度解析:打破流量孤岛,构建企业增长新闭环 - GEORANK
  • 用 AI 改造一个 Flink SQL 项目:从脚本提交到数据同步平台
  • 2026年上海网约车租赁公司怎么选?双证合规+新能源+无隐形收费的靠谱服务商完全指南 - 优质企业观察收录
  • 10-杨逢昌:6S检查表设计——一张好表胜过十次口头强调,附评分标准
  • 2026年贵阳铁签烤肉怎么选?花果园、南明区正宗老贵阳烤肉店深度横评 - 优质企业观察收录
  • 响应谱分析-理论
  • 2026年6月盐城亭湖区黄金回收行情与变现策略 - 上门黄金回收
  • 生产级机器学习系统设计:从模型部署到契约化治理
  • 数据模型如何应对黑天鹅事件:从脆弱性到反脆弱性
  • CANN GE图编译器架构原理:从计算图优化到多流并行与内存复用技术内幕
  • 开店必看!成都火锅底料厂家测评避坑指南 - 资讯报道
  • 2026全球EMBA行业偏向及中立选型测评分析
  • 青岛卖黄金别踩坑 2026年6月回收门店盘点 - 余生黄金回收
  • 爱马仕LV怎么卖高价?佛山正规包包回收门店实测 - 讯息早知道
  • 抖音无水印下载器终极指南:5分钟掌握批量下载神器
  • 在沈阳卖名表找这家,线上估价上门秒打款 - 逸程
  • 微信群怎么发起视频投票?线上视频投票制作完整操作教程 - 微信投票小程序
  • 主城旧金变现实测,奢二网光谱验金计价流程全公开 - 讯息早知道
  • HsMod终极指南:炉石传说50+功能插件完整配置手册
  • 阿里给机器人造了个“通用大脑“,但谁来给 AI 开发者造“商业大脑“?
  • 2026年6月精选重庆职称评审代办机构推荐榜 5类服务与选择指南 - 资讯焦点
  • 2026年纸托模具制造厂家实力观察:东莞昆保达的环保包装之路 - 资讯焦点
  • 正则化实战指南:从过拟合诊断到L1/L2/Elastic Net调参