5.2 bind-mount 挂载现场:-v 与 --mount 的完整义项


5.2 bind-mount 挂载现场:-v 与 --mount 的完整义项

本节摘要:绑定挂载(bind mount)把宿主机上的既有目录原样递给容器:宿主机改文件、容器立即看见,容器写日志、宿主机直接可读。本节对比 -v 与 --mount 两种语法,给全只读、传播模式等义项,并跑通"改代码不重建镜像"的开发现场,收录权限映射与文件事件两个高频坑。

开发者的日常痛点:代码改一行,得重建镜像、重启容器才能验证——绑定挂载就是为此而生的词条。它不做任何搬运与管理,就是把宿主机的一个目录"过户"给容器的某个路径,两边看到的是同一份文件。理解它之后,开发环境、配置注入、日志外送都会变得直白。

词条卡:-v 与 --mount 两种语法

# -v 写法:冒号分隔,紧凑但含义靠位置区分 docker run -v 卷名或路径:容器路径[:ro] ... # --mount 写法:键值对显式,字段名自解释 docker run --mount type=bind,src=宿主路径,dst=容器路径[,readonly] ...
维度 -v --mount
语法风格 位置传参,紧凑 键值传参,冗长但无歧义
宿主路径不存在 自动创建目录(易掩盖手误) 直接报错(更安全)
卷与绑定挂载 同一选项,靠首字符区分(斜杠开头即路径) type=volume / type=bind 显式声明
适用 手敲命令、快速实验 脚本、Compose、文档

同一个意图的两种写法:

$ docker run --rm -v /home/ops/app:/work debian:12-slim ls /work main.py requirements.txt $ docker run --rm --mount type=bind,src=/home/ops/app,dst=/work \ debian:12-slim ls /work main.py requirements.txt

功能等价。本节词条约定:手敲示范用 -v,进脚本前改写成 --mount——它对"路径不存在"的处理是报错而非悄悄建目录,能拦住不少拼写事故。

挂载语义:三种来源一张图

挂载语义:三种来源一张图

这张图把 -v 最容易犯迷糊的地方钉死:冒号前第一个字符是什么,决定了整条挂载的性质。名字、斜杠、空缺,三种形态三种命运。

现场:改代码不重建镜像

$ cat /home/ops/app/main.py print("v1") $ docker run --rm -v /home/ops/app:/src -w /src python:3.12-slim python main.py v1 $ sed -i 's/v1/v2/' /home/ops/app/main.py $ docker run --rm -v /home/ops/app:/src -w /src python:3.12-slim python main.py v2

-w 指定容器工作目录(叁部前后台组的义项),代码从宿主机借来,解释器从镜像里来——宿主机只需要 Python 之外的依赖,环境一致性由镜像保证,代码迭代由绑定挂载实时同步。Web 服务同理:把代码目录挂进 nginx 或框架容器,改完保存、刷新页面即生效,镜像里那份代码成了出厂备份。

配置注入与只读收紧

$ docker run -d --name nginx-secure \ -v /srv/nginx/nginx.conf:/etc/nginx/nginx.conf:ro \ -v /srv/nginx/certs:/etc/nginx/certs:ro \ -p 443:443 nginx:1.25

配置与证书从宿主机注入,:ro 把容器的影响面收窄到只读——容器即便被攻破,也改不了宿主机上的这两样东西。凡是"宿主机提供、容器消费"的文件(时区、证书、配置、密钥),一律建议 ro。核对挂载关系用 inspect:

$ docker inspect nginx-secure --format '{{json .Mounts}}' | python3 -m json.tool [ { "Type": "bind", "Source": "/srv/nginx/nginx.conf", "Destination": "/etc/nginx/nginx.conf", "Mode": "ro", "RW": false, "Propagation": "rprivate" } ]

⚠️ 常见坑:容器内进程的 UID 与宿主机文件属主不匹配,写挂载目录时报 Permission denied。Linux 下容器默认以镜像声明的用户(常为 root)跑,root 写普通文件通常畅通;反倒是"容器内非 root 用户 + 宿主机属主是别的用户"的组合必撞墙。处置要么对齐 UID(构建时指定),要么放宽宿主机目录权限,别用 chmod 777 掩盖问题。

坑二:文件事件丢失

编辑器保存文件常用"写临时文件再原子改名"的策略,在 macOS 与 Windows 的虚拟机文件系统上,改名事件可能不触发容器内框架的热重载监视器——症状是宿主机明明保存了,容器里毫无反应。处置办法按环境固定:开发工具里关闭原子保存,或热重载器开启轮询模式(如多数框架的 watch 选项),代价是一些 CPU 占用。

延伸现场:多容器共享与传播模式

绑一个目录给多个容器是常态——业务容器写日志,采集容器只读同一份:

$ docker run -d --name app-log -v /srv/logs:/logs busybox:1.36 \ sh -c 'while true; do echo "beat $(date +%T)" >> /logs/app.log; sleep 5; done' $ docker run --rm -v /srv/logs:/logs:ro busybox:1.36 cat /logs/app.log beat 09:31:05 beat 09:31:10

写方 rw、读方 ro,一份目录两种权限,采集与业务互不越界。同宿主机内的多容器共享,绑定挂载与命名卷都胜任;要跨宿主机共享才轮到网络存储出场,那超出本册的命令范围,先记住边界。

传播模式(Mounts 数组里的 Propagation 字段)管的是"宿主机后续的挂载变化,容器看不看得见"。默认 rprivate:两边互不相干;rslave:宿主机新挂的子目录容器能看到;rshared 再进一步,容器内的挂载也回传宿主机。九成场景默认值即可,剩下的一成出现在往挂载目录里再嵌套挂载的编排现场,遇到再查。

💡 判断口诀:数据的"真身"在谁手里,就按谁的方式管。真身在宿主机目录,用 mv、rm、chown 这些宿主机手段;真身在卷里,用 volume 命令族。两套工具别用反,是绑定挂载现场最常见的秩序问题。

本节要点回顾

  • 绑定挂载是原地借出:不搬运、不托管,宿主机与容器看同一份文件。
  • -v 靠首字符定语义:名字是卷、斜杠是绑定、空缺是匿名卷;--mount 显式且报错早。
  • 开发热改的标准姿势:代码挂进去、依赖装在镜像里,改完即生效。
  • ro 是纪律:宿主机供、容器耗的文件一律只读。
  • 两大坑各有解:权限错位对齐 UID,事件丢失关原子保存或开轮询。

绑定挂载的数据永远留在宿主机,命名卷的数据永远躺在磁盘——如果有些数据压根不想留下呢?tmpfs 词条登场。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U