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

docker run -v /宿主机/路径:/容器/路径 即绑定挂载,实时双向同步;加 :ro 只读。Dockerfile 里不能做主机挂载(不可移植),ADD/COPY 是构建期拷贝不是挂载。本文讲清区别与坑。

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

做法:docker run -v /host/dir:/container/dir 镜像——绑定挂载(bind mount),宿主机目录与容器目录实时同步,容器删了宿主机文件还在。注意 Dockerfile 里无法做主机挂载(镜像要可移植,宿主路径因机而异),挂载只能在运行时指定;Dockerfile 的 ADD/COPY 是构建期拷贝副本,后续改动不同步。

基本用法

# 挂载配置目录
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. 宿主机目录不存在:Docker 会自动创建为 root 属主的空目录——多半不是你要的,挂载前先确认路径
  2. 权限不匹配:容器内进程 UID 与宿主机文件属主不一致导致读写失败,按需 chown 或用 --user 对齐
  3. SELinux(RHEL/CentOS):挂载加 :z:Z 重新打标签,否则容器内 permission denied
  4. 挂载单文件后被编辑器覆盖:vim 等编辑器"另存替换"会换 inode,挂载的单文件句柄失效——改挂载其所在目录

挂载 vs 命名卷

配置、代码、要直接查看的日志 → 绑定挂载;数据库数据等应用自管理的数据 → 命名卷更省心(权限初始化 Docker 会帮忙做)。

观测云对照

日志目录挂载后采集更直接。 应用日志目录绑定挂载到宿主机规范路径(如 /var/log/apps/),DataKit 按主机路径采集,容器重建、多副本扩缩都不影响日志链路。

常见问题(FAQ)

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

Q:Mac/Windows 上挂载很慢?
A:Desktop 的虚拟化文件共享开销大,大目录用命名卷或 delegated 挂载选项改善。

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

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

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

立即开始

选择观测云版本

代码托管平台