如何把宿主机目录挂载进 Docker 容器?

docker run -v /宿主机/路径:/容器/路径 即绑定挂载,共享文件系统视图;加 :ro 只读。Dockerfile 不能声明部署时的宿主机绑定挂载,ADD/COPY 是构建期拷贝不是挂载。本文讲清区别与坑。

最佳实践
如何把宿主机目录挂载进 Docker 容器?封面

做法:docker run -v /host/dir:/container/dir 镜像——绑定挂载(bind mount),容器访问的是宿主机目录的文件系统视图,不是两个目录的同步副本;删除容器不删除该目录,但容器内删除挂载文件也会影响宿主机。部署时的绑定挂载在运行配置中指定;Dockerfile 的 RUN --mount=type=bind 则是构建步骤内的临时挂载,不会固化运行时挂载;Dockerfile 的 ADD/COPY 是构建期拷贝副本,后续改动不同步。

这里的宿主机指 Docker daemon 所在主机;远程 Docker 客户端不能直接把本机目录作为远端 daemon 的绑定源。

基本用法

# 挂载配置目录
docker run -d -v /opt/app/conf:/etc/app/conf myimage

# 只读挂载(配置防改)
docker run -d -v /opt/app/conf:/etc/app/conf:ro myimage

# 挂载单个文件
docker run -d -v /opt/app/app.yml:/etc/app/app.yml myimage

compose 写法:

services:
  app:
    volumes:
      - /opt/app/conf:/etc/app/conf:ro
      - ./logs:/var/log/app

与 ADD/COPY 的本质区别

绑定挂载(-v) ADD/COPY(Dockerfile)
时机 运行时 构建时
宿主机后续改动 访问同一文件系统视图,仍受应用缓存等影响 不可见(拷的是当时的副本)
容器删除后 数据保留在宿主机 镜像层不动,容器层丢失
可移植性 依赖宿主路径 镜像自给自足

常见坑

  1. 宿主机目录不存在:-v 会创建缺失路径为目录;--mount type=bind 默认会报错。属主还取决于 daemon 与用户映射,挂载前先确认路径
  2. 权限不匹配:容器内进程 UID 与宿主机文件属主不一致导致读写失败,按需 chown 或用 --user 对齐
  3. SELinux(RHEL/CentOS):挂载加 :z 或 :Z 重新打标签,否则容器内 permission denied
  4. 挂载单文件后被编辑器覆盖:vim 等编辑器"另存替换"会换 inode,挂载仍可能指向旧 inode,读不到替换后的文件——可改挂载其所在目录

挂载 vs 命名卷

配置、代码、要直接查看的日志 → 绑定挂载;数据库数据等应用自管理的数据 → 命名卷便于管理,但应用需要的 UID/GID、权限及初始化仍要核对。

日志目录使用绑定挂载时,先核对宿主机路径和文件属主。观测云 DataKit 可按文件采集配置读取该路径;容器重建后再写一条测试日志,检查是否仍能采集,避免多个副本写入同名文件后无法区分来源。

常见问题(FAQ)

Q:容器内写入的文件在宿主机看不到?
A:确认挂载方向没写反(左边是宿主机);容器内写到了挂载点之外的路径也会"看不到"。

Q:Mac/Windows 上挂载很慢?
A:性能取决于 Desktop 版本与文件共享后端;可测试命名卷或当前版本的同步文件共享功能,不能保证 delegated 在所有后端都有效。

Q:能挂载不存在的容器路径吗?
A:会照挂——容器内该路径被遮蔽成挂载内容,镜像里原有的同路径文件被盖住。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台